php - job - Pasando los parámetros $_GET al trabajo cron
Soy nuevo en cron jobs y no estoy seguro de si esto funcionaría.
Por motivos de seguridad, pensé en hacer un script de una página que busque ciertos valores GET (un nombre de usuario, una contraseña y un código de seguridad) para asegurarme de que solo la computadora y alguien que sepa los 3 puedan ejecutar el comando.
Hice el script y funciona ejecutándolo en un navegador, pero ¿es posible ejecutar el trabajo cron con valores GET?
un ejemplo sería yo corriendo
* 3 * * * /path_to_script/cronjob.php?username=test&password=test&code=1234
es posible?
Esto funcionará:
* 3 * * * /path_to_script/cronjob.php username=test password=test code=1234
Las $_GET[]
y $_POST[]
solo se inicializan cuando su script se invoca a través de un servidor web. Cuando se invoca a través de la línea de comandos, los parámetros se pasan en la matriz $argv
, como C.
Contiene una matriz de todos los argumentos pasados al script cuando se ejecuta desde la línea de comando.
Tu comando sería:
* 3 * * * /path_to_script/cronjob.php username=test password=test code=1234
Luego usaría parse_str() para establecer y acceder a los parámetros:
<?php
var_dump($argv);
/*
array(4) {
[0]=>
string(27) "/path_to_script/cronjob.php"
[1]=>
string(13) "username=test"
[2]=>
string(13) "password=test"
[3]=>
string(9) "code=1234"
}
*/
parse_str($argv[3], $params);
echo $params[''code'']; // 1234
Me doy cuenta de que esta publicación ya tiene varios años, pero esta fue la que más me ayudó, así que permítame compartir mis descubrimientos para ayudar a otros también.
Estoy usando DirectAdmin y mis ejemplos cron están funcionando a la vez. Eliminé mi dirección de correo electrónico de ''Enviar todas las salidas de Cron al correo electrónico'', por lo que no recibo notificaciones de correo electrónico de mis cronjobs.
Comencé con una solicitud de CURL que se ejecuta cada 20 minutos:
*/20 * * * * /usr/local/bin/curl --silent ''https://demo.tld/app/stats/?update&key=1234''
Tenga en cuenta '''' alrededor de la URL, de lo contrario, no puede agregar múltiples parámetros.
Utilizo esa página como una forma inspirada en la API para activar la actualización de algunas estadísticas que recojo de otro sitio web y que otros pueden tomar en forma JSON desde la mía. El parámetro ''actualización'' desencadena el proceso de actualización y la ''clave'' del parámetro, cuando se valida, desencadena acciones de actualización adicionales que solo quiero hacer cuando el cronjob solicita la actualización.
Dado que el cronjob anterior básicamente consume ancho de banda en ambas direcciones, quería ir para un cronjob basado en PHP, pero tuve un problema con los parámetros ... así que fue cuando encontré esta publicación que me salvó el día :)
*/20 * * * * /usr/local/bin/php /home/path/to/public_html/app/stats/index.php update key=1234
Como puede ver, el nombre de archivo (index.php) ahora está incluido en la ruta y luego los parámetros siguen (sin los? Y & ''s).
De esta manera, el cronjob está funcionando, PERO estás solo a mitad de camino, ya que los parámetros no se transmitirán a través de $_GET
... ¡lo cual es un poco molesto cuando has codificado tu script con cheques para las teclas $_GET
!
Entonces, ¿cómo funciona entonces? Simple (al menos después de algunas investigaciones), el cronjob pasa los parámetros al script a través de una variable llamada $argv
.
Así que con ese conocimiento busqué un método para transformar $argv
en $_GET
así que:
- Puedo activar la actualización tanto manualmente como a través del cronjob.
- No tuve que volver a escribir todo el script.
Encontré la siguiente solución que solo queremos ejecutar cuando realmente se establece $argv
, así que la envolví en la comprobación if isset
:
if( isset( $argv ) )
{
foreach( $argv as $arg ) {
$e = explode( ''='', $arg );
if( count($e) == 2 )
$_GET[$e[0]] = $e[1];
else
$_GET[$e[0]] = 0;
}
}
Espero que esto le ayude también :)
Me resulta útil usar la función getopt()
cuando necesito parámetros de un comando cron o de consola.
Esta función devolverá una matriz de pares de opciones / argumentos, o FALSE en caso de error.
Los siguientes ejemplos han sido tomados directamente de la documentación de PHP.
$options = getopt("f:hp:");
var_dump($options);
shell> php example.php -fvalue -h
El ejemplo anterior dará como resultado:
array(2) {
["f"]=>
string(5) "value"
["h"]=>
bool(false)
}
Para obtener más opciones y diferentes parámetros, eche un vistazo a la documentación completa.
Recursos
No es una respuesta directa a su pregunta, sino una mejor solución, creo:
Si no quiere que nadie, excepto cron, ejecute el script, solo colóquelo fuera de la raíz web. De esa forma, no hay acceso a través del servidor web.
Si también necesita ejecutar el comando como un usuario especial, no use GET
, haga que el usuario inicie sesión y verifique que haya una sesión iniciada (una determinada variable de sesión determinada) e incluya el script en esa página solamente.
Su secuencia de comandos de acceso público sería algo así como:
session_start();
if (isset($_SESSION[''user'']))
{
include ''/path/to/script/outside/of/web-root'';
}
else
{
die(''No access.'');
}
username=test&password=test&code=1234
se convirtió en
php -r "$_GET["username"]="test"; $_GET["password"]="test"; $_GET["code"]="1234"; include "wp-cron.php";''
* 3 * * * /path_to_script/cronjob.php?username=test&password=test&code=1234
Esto no funcionará
* 3 * * * /path_to_script/cronjob.php username=test password=test code=1234
Esto funciona
Además, necesita usar la función parse_str () y obtener valor
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
echo $first; // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz