How to get PHP executable

Howdy there :wave:

I’m having trouble figuring out how to use the Local Add-on API to retrieve the PHP executable path. Can anyone help point me in the right direction?

I would like to be able to display the PHP executable path for the site in the renderer.js file similar to the way the Site Name is displayed in the code below.

import React, { useState, useEffect } from 'react';
import { TableListRow } from '@getflywheel/local-components';

export default function (context) {
	const { hooks } = context;

	hooks.addContent('siteInfoUtilities', (site) => {
		const [siteName, setSiteName] = useState<string | null>(null);
		const [phpExePath, setPhpExePath] = useState<string | null>(null);

		useEffect(() => {
			const siteName = site.name;
			setSiteName(siteName);
		}, [site.name]);

		return (
			<TableListRow key="site-info-stuff" label="Site Info">
				<p>
					Site Name: {siteName}<br/>
					PHP executable path: {phpExePath}<br/>
				</p>
			</TableListRow>
		);
	});

}

Thanks!

These might be helpful for you @picklebrownie

Thanks, Nick for the reply.

I understand how to manually find the PHP executable path, but I would like to do it programmatically. For example, using the Local Add-on Hook site (documentation here), we should be able to retrieve the PHP version using site.phpVersion. I’m developing an add-on and need to be able to save the executable path in a const for later use.

@picklebrownie The PHP path is determined dynamically depending on the OS and system architecture, which is why it’s not available on the site object.

To display it in a component, you could use an IPC call. For example:

main.ts

import * as LocalMain from '@getflywheel/local/main';

export default function (context: LocalMain.AddonMainContext): void {
	const { electron } = context;
	const { ipcMain } = electron;
	const { siteData, lightningServices } = LocalMain.getServiceContainer().cradle;

	ipcMain.on('get-php-bin-path', (event, siteId) => {
		const site = siteData.getSite(siteId);
		const services = lightningServices.getSiteServices(site);
		const phpService = services.find((service) => service.serviceName === 'php');
		const phpBinPath = phpService?.bin;

		event.sender.send('php-bin-path', phpBinPath);
	});
}

renderer.jsx

import Boilerplate from './Boilerplate';
import fs from 'fs-extra';
import path from 'path';

const packageJSON = fs.readJsonSync(path.join(__dirname, '../package.json'));
const addonID = packageJSON.slug;

export default function (context) {
	const { React, hooks } = context;

	hooks.addFilter('siteInfoToolsItem', (menu) => [
		...menu,
		{
			menuItem: 'Counter',
			path: `/${addonID}`,
			render: (props) => <Boilerplate {...props} />,
		},
	]);
}

Boilerplate.jsx

import React, { useState, useEffect } from "react";
import { ipcRenderer } from "electron";

const Boilerplate = (props) => {
	const [siteId] = useState(props.site?.id);
	const [phpBinPath, setPhpBinPath] = useState("");

	useEffect(() => {
		ipcRenderer.send("get-php-bin-path", siteId);
		ipcRenderer.on("php-bin-path", (event, phpBinPath) => {
			setPhpBinPath(phpBinPath);
		});

		return () => {
			ipcRenderer.removeAllListeners("php-bin-path");
		};
	}, []);

	return (
		<div style={{ flex: "1", overflowY: "auto", margin: "10px" }}>
			<p>PHP Bin Path: {JSON.stringify(phpBinPath)}</p>
		</div>
	);
};

export default Boilerplate;

Resulting in this:

If you just want the php path you can use phpBinPath.php instead of the full phpBinPath object (which gives php-fpm and php-cgi paths too).

3 Likes

Thank you, @nickc
This worked beautifully.

2 Likes

This topic was automatically closed 36 hours after the last reply. New replies are no longer allowed.