For reference, this is how we get the variable value:
#!/usr/bin/php
<?php
// all KM variables are stored in $_ENV which is an array.
$envVariableArray = $_ENV;
// this is how we get the value of the KM variable "VarName"
echo $envVariableArray["KMVAR_VarName"];
?>
Now, setting KM variables in PHP are tricky.
I'll give my conclusion here first: If we want to set KM variables, the proper way is to use osascript.
To demonstrate the point, I've made a PHP script:
#!/usr/bin/php
<?php
//###########################################//
// This PHP code demonstrates how to get variables from KM in PHP
//-----------------------------------------------------------------------//
// Beside passing via Command Line arguments,
// there are three ways to get the value of KM variable:
// 1. use $_ENV["KMVAR_VarName"]
// 2. use getenv("KMVAR_VarName")
// 3. use osascript
//-----------------------------------------------------------------------//
// Initially, all three should get the same value.
// However, they are actually independent from each other.
// We will see it clearly once we set new value to any of them.
//###########################################//
//###########################################//
// assume the value of VarName in KM is "initial value";
//###########################################//
echo "Before setting any variables in PHP \n";
echo "\n".'-Variable value via $_ENV:'."\n";
echo $_ENV["KMVAR_VarName"];
echo "\n".'-Variable value var getenv():'."\n";
echo getenv("KMVAR_VarName");
echo "\n".'-Variable value via osascript:'."\n";
echo exec('osascript -e \'tell application "Keyboard Maestro Engine" to getvariable "VarName"\'');
echo "\n\nEND\n\n\n";
// All will output "initial value"
//###########################################//
$_ENV["KMVAR_VarName"] = "Value set via ENV";
//-----------------------------------------------------------------------//
// this will NOT change the value of VarName in KM.
//-----------------------------------------------------------------------//
echo "After setting variable via '\$_ENV' \n";
echo "\n".'-Variable value via $_ENV:'."\n";
echo $_ENV["KMVAR_VarName"];
echo "\n".'-Variable value var getenv():'."\n";
echo getenv("KMVAR_VarName");
echo "\n".'-Variable value via osascript:'."\n";
echo exec('osascript -e \'tell application "Keyboard Maestro Engine" to getvariable "VarName"\'');
echo "\n\nEND\n\n\n";
//###########################################//
// Only $_ENV["KMVAR_VarName"] is affected.
//###########################################//
$myVar = "Value set via putenv";
putenv("KMVAR_VarName=$myVar");
//-----------------------------------------------------------------------//
// this will NOT change the value of VarName in KM either.
//-----------------------------------------------------------------------//
echo "After setting variable via 'putenv()' \n";
echo "\n".'-Variable value via $_ENV:'."\n";
echo $_ENV["KMVAR_VarName"];
echo "\n".'-Variable value var getenv():'."\n";
echo getenv("KMVAR_VarName");
echo "\n".'-Variable value via osascript:'."\n";
echo exec('osascript -e \'tell application "Keyboard Maestro Engine" to getvariable "VarName"\'');
echo "\n\nEND\n\n\n";
//###########################################//
// Only getenv("KMVAR_VarName") is affected.
//###########################################//
// use osascript to set KM variables.
exec('osascript -e \'tell application "Keyboard Maestro Engine" to setvariable "VarName" to "new value"\'');
//-----------------------------------------------------------------------//
// This will change the variable value in KM.
// But $ENV and getenv remain the same values as before the osascript
//###########################################//
echo "After setting variable via osascript \n";
echo "\n".'-Variable value via $_ENV:'."\n";
echo $_ENV["KMVAR_VarName"];
echo "\n".'-Variable value var getenv():'."\n";
echo getenv("KMVAR_VarName");
echo "\n".'-Variable value via osascript:'."\n";
echo exec('osascript -e \'tell application "Keyboard Maestro Engine" to getvariable "VarName"\'');
echo "\n\nEND\n\n";
// Only osascript getvariable is affected.
//###########################################//
// Conclusion on $_ENV, getenv(), and osascript in PHP:
// Before changing the variable values, all three methods will get the KM variable values.
// But they are all independent from each other.
// Changing variable values of one will not change that of the other two.
// If we want to set KM variables, the proper way is to use osascript.
//###########################################//
?>
I've figured out a way to use PHP variables. to set KM variables.
Here is the code:
#!/usr/bin/php
<?php
//###########################################################//
//## This PHP code demonstrates how to set KM variables using osascript ##
//###########################################################//
$kmVarName = "VarName";
$kmVarValue = "this is the new value\nthe 2nd line\nthe 3rd line";
exec('osascript -e \'tell application "Keyboard Maestro Engine" to setvariable "' . $kmVarName . '" to "'. $kmVarValue .'"\'');
?>
I've noticed a problem.
Getting KM variable values using osascript will get only the last line of the variable value. @peternlewis and @ccstone, is this a bug?
After setting the KM variable via osascript, $_ENV["KMVAR_VarName"]; and getenv("KMVAR_VarName"); no longer reflect the new KM variable value. I don't know other ways to get the new KM variable value except using osascript. But if osascript gets only the last line of the variable value, it is not reliable.
(To set a KM variable and then read it back to PHP is a rare case. It is probably never needed. If we need the new value, we can update the variable within the PHP code. So practically, it might not be a problem at all. But getting only the last line of the variable value via osascript getvariable is an unexpected behavior.)
Of course not. Environment variables are local to the process, and are configured when the process launched, after which they can only be modified within the process.
Keyboard Maestro sets them up when it launches the process from the variable values at that time - any changes to Keyboard Maestro variables after that will not affect the environment variables.
Undoubtedly, but it is likely a bug in your code or in PHP’s handling of things, or your handling of the different line endings. Line endings on the Mac vary between \r and \n (and rarely \r\n).
tell application "Keyboard Maestro Engine"
setvariable "Test" to "Hello\nThere\n"
set x to getvariable "Test"
end tell
Works fine, sets the Test variable to two lines, reads the text variable, both lines, displays it in a window.
In this case, you probably want to use \r instead of \n.
The problem is the variable value might already contain \n.
I think I've found the issue. The exec('osascript ...AppleScript...', $output) command return the result as an array, whose elements are lines of the variable value.
array(3) {
[0]=>
string(21) "this is the new value"
[1]=>
string(12) "the 2nd line"
[2]=>
string(12) "the 3rd line"
}
Edit:
The exec() command returns the last line of the variable.
From PHP: exec - Manual:
[exec() returns] The last line from the result of the command. If you need to execute a command and have all the data from the command passed directly back without any interference, use the passthru() function.
Just add one point.
If $_ENV does not get the variable value, it is probably because in the php.ini file E is not included in variables_order.
We can of course add E to variables_order in the php.ini file.
To get the php.ini file, we can
run php -i | grep php.ini to locate the php.ini file. In my case, it is located at /usr/local/etc/php/8.0.
Open the file and search for variables_order. It looks like variables_order = "GPCS". Just add E to it.
However, since we can also get the variable with getenv("KMVAR_VarName");, we don't actually need $_ENV["KMVAR_VarName"];.
This is the instruction in the php.ini file regarding $_ENV:
; This directive determines which super global arrays are registered when PHP
; starts up. G,P,C,E & S are abbreviations for the following respective super
; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
; paid for the registration of these arrays and because ENV is not as commonly
; used as the others, ENV is not recommended on productions servers. You
; can still get access to the environment variables through getenv() should you
; need to.
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
variables_order = "GPCS"
To set KM variables in PHP, we still need to use osascript:
$kmVarName = "VarName";
$kmVarValue = "this is the new value\nthe 2nd line\nthe 3rd line";
exec('osascript -e \'tell application "Keyboard Maestro Engine" to setvariable "' . $kmVarName . '" to "'. $kmVarValue .'"\'');
Of course, as also has been said, we can use osascript to get KM variables.