Reputation: 1475
Is there any way I can pass parameters (like Query string in URL, or URL parameters) to a PHP file which is being run via CLI? I need this for some PHP cron jobs which need input from parameters. For example:
$ php /home/abc/www/myphp.php?param1=abc
Upvotes: 6
Views: 13204
Reputation: 7249
if (PHP_SAPI === 'cli')
{
parse_str(implode('&', array_slice($argv, 1)), $_GET);
}
This is solution that I use, if running via cli, put vars and values in $_GET, seems that is working for simple tasks , not sure if work with php getopt etc
Upvotes: 0
Reputation: 1
I needed to do the same thing, pass query parameters to a php script to run as a cron job. The script was from a third party and I didn't want to modify or write a new script. The solution was to place the query string parameters in single quotes and replace the question mark with an ampersand. In my case, I pass three parameters.
php /home/abc/www/myphp.php '¶m1=abc¶m2=def¶m3=123'
I found the solution in this post, tried it and it works fine for me.
Upvotes: 0
Reputation: 879
There are two special variables in every command line interface argc
and argv
.
argv
- array of arguments passed to the script.
argc
- the number of command line parameters passed to the script (if run on the command line).
Make script cli.php
<?php
print_r($_SERVER['argv']);
and call it with argument:
$ php cli.php argument1=1
You should get the output looking like:
Array
(
[0] => cli.php
[1] => argument1=1
)
Source: http://www.php.net/manual/en/reserved.variables.server.php
If you are still so demanding to have a single point entry and to be able to process the url query as $_GET make your script act like a router by adding a switch:
if (PHP_SAPI === 'cli')
{
// ... BUILD $_GET array from argv[0]
}
But then - it violates SRP - Single Responsibility Principle! Having that in mind if you're still so demanding to make it work like you stated in the question you can do it like:
if (PHP_SAPI === 'cli')
{
/** ... BUILD from argv[0], by parsing the query string, a new array and
* name it $data or at will
*/
}
else
{
// ... BUILD new $data array from $_GET array
}
After that convert the code to use $data array instead of $_GET
...and have a nice day!
Upvotes: 7
Reputation: 146430
If the underlying code absolutely requires $_GET
(and does not rely on other HTTP features) you can write a simple wrapper that abuses the fact that isn't a read-only superglobal:
<?php
// Untested (tweak to your own needs)
foreach($argv as $i){
list($k, $v) = explode('=', $i, 2);
$_GET[$k] = $v;
}
require_once('/home/abc/www/myphp.php');
... and then schedule your proxy instead:
php /path/to/wrapper.php param1=abc
Upvotes: 2
Reputation: 39532
Here's an extracted/rewritten class from my CLI Application library using $_SERVER['argv']
in the same form that linux runs commands (foo.sh --param "value" --marap
):
<?php
class ArgumentScanner {
private static $instance;
private $arguments;
public static function get() {
if (empty(self::$instance)) {
self::$instance = new ArgumentScanner();
}
return self::$instance;
}
public function __construct() {
$this->arguments = $this->parseArguments($_SERVER['argv']);
}
public function __isset($argument) {
return isset($this->arguments[$argument]);
}
public function __get($argument) {
return (isset($this->arguments[$argument]) ? $this->arguments[$argument] : null);
}
/**
* Is used to parse the contents of $_SERVER['argv']
* @param array $argumentsRaw The arguments from $_SERVER['argv']
* @return stdClass An object of properties in key-value pairs
*/
private function parseArguments($argumentsRaw) {
$argumentBuffer = '';
foreach ($argumentsRaw as $argument) {
if ($argument[0] == '-') {
$argumentBuffer = substr($argument, ($argument[1] == '-' ? 2 : 1));
$equalSign = strpos($argumentBuffer, '=');
if ($equalSign !== false) {
$argumentKey = substr($argumentBuffer, 0, $equalSign);
$argumentsParsed[$argumentKey] = substr($argumentBuffer, $equalSign + 1);
$argumentBuffer = '';
} else {
$argumentKey = $argumentBuffer;
$argumentsParsed[$argumentKey] = '';
}
} else {
if ($argumentBuffer != '') {
$argumentKey = $argumentBuffer;
$argumentsParsed[$argumentKey] = $argument;
$argumentBuffer = '';
}
}
}
return (object)$argumentsParsed;
}
}
?>
Use:
<?php
$argumentScanner = ArgumentScanner::get();
if (isset($argumentScanner->reset)) {
echo '--reset was passed!';
}
if (isset($argumentScanner->test)) {
echo '--test was passed as ' . $argumentScanner->test . '!';
}
if (isset($argumentScanner->foo)) {
echo '--foo was passed as ' . $argumentScanner->foo . '!';
}
if (isset($argumentScanner->bar)) {
echo '--bar was passed as ' . $argumentScanner->bar . '!';
}
?>
php script.php --foo "bar" --reset -test="hey you!"
Output:
--reset was passed!
--test was passed as hey you!
--foo was passed as bar!
Upvotes: 1
Reputation: 1013
Best solution there would be to refactor and abstract away the business logic, retain the original script as a wrapper for it. Then add a CLI script to wrap the same business logic for the CLI. That way, you can use the normal CLI parameter handling: http://www.php.net/manual/en/reserved.variables.argv.php
Upvotes: 0
Reputation: 6274
try wget and output to null
wget http://localhost/myphp.php?param1=abc -o /dev/null
Upvotes: -1