Execute PHP via cron - No Input file specified - php

I'm using the following command to execute a PHP file via cron
php -q /home/seilings/public_html/dvd/cron/mailer.php
The problem is that I Have a file that's included in the execution that determines which config to load.... such as the following:
if (!strstr(getenv('HTTP_HOST'), ".com")) {
$config["mode"] = "local";
} else {
$config["mode"] = "live";
}
The cron is loading the LOCAL config when it should be loading the LIVE config. I've tried using the http:// URL to the file instead of the absolute path but it didn't find the file. Do I need to change the command to use a URL within it?

Another simple solution:
cron:
php -q /home/seilings/public_html/dvd/cron/mailer.php local
php:
if (!empty($argv[0])) {
$config["mode"] = "local";
} else {
$config["mode"] = "live";
}

Use this php_sapi_name() to check if the script was called on commandline:
if (php_sapi_name() === 'cli' OR !strstr(getenv('HTTP_HOST'), ".com")) {
$config["mode"] = "local";
} else {
$config["mode"] = "live";
}
If you want to use "live" on the commandline use this code:
if (php_sapi_name() === 'cli' OR strstr(getenv('HTTP_HOST'), ".com")) {
$config["mode"] = "live";
} else {
$config["mode"] = "local";
}

When you run the php with cron it is very likely that then environment variable 'HTTP_HOST' will not be set (or null) and when null is given to strstr function, strstr returns false that is why the mode is set to "local".

You're probably getting a different set of environment variables when you execute your command via cron, versus the command line. You might need to write a wrapper script that sets the environment up the way you want it before running your PHP command.

Enviroment variable such as HTTP_HOST exists only when you're running php scrints under web server. But you can add it manually in your crontab config:
## somewhere in crontab config
HTTP_HOST=somthing.com
15 * * * * /path/to/your/script > /dev/null 2>&1
This will enable your script to think that it's running on production enviroment.

If you're feeling lazy and do not feel like making sure all those env variables work you might want to try running with cron using:
lynx -dump http://url.to.your.script > /dev/null

Related

PHP misses system variables when using exec

So i have a project where I send spotify track URL to server and store it. I use laragon with PHP 7.4 installed, windows 11. I use that downloader. It works via cmd command line. When I try to use it by hand it works fine, but when i send it by exec() it doesn't work. I can't get any return message neither. I have tried using exec(), system() and shell_exec() functions. The problem might be with with system variables, as these might not be visible for PHP. I have also tried turning on/off server and it didn't work. I have also tried to put putenv('PATH=' . $_SERVER['PATH']) at the beginning of file. I tried to check laragon path variables itself - I couldn't see these i have added. Any other default windows commands works as should be. Any ideas on how to fix it?
Here is my PHP code:
function createFile($url, $token){
function execCommand($dir, $url){
$command1 = "cd $dir";
$command2 = "spotdl $url";
if(!shell_exec($command1. "&& ". $command2)) return false;
return true;
}
$path = "C:\Laragon/laragon/www/temp/";
$dir = $path.$token.'/';
if(!mkdir($dir, 0777)) throwError("Server error");
if(!execCommand($dir, $url)) return false;
return true;
}
I know i'm not returning any output from console, but that is post updates. Second command is definitely beeing called, i have tested it on some other commands (like mkdir)
In many os the errors output (stderr) of the commands isn't the same that the normal output (stdout), you need to redirect the errors to the stdout. so the command must be:
$ command $arg1 $arg2 ... 2>&1
This cause that the errors messages will be sent to the stdout, Is util remember this when you are working with system calls.
Now in your code i prefer to use the exec function in php
<?php
$result = 0;
$output = [];
$command = "your command with the 2>&1";
exec($command, $output, $result);
if ($result != 0) {
// here an error ocurred and you can see the error on the ouput array
exit();
}
// here you know that the command was executed successfully
After re-installing laragon it worked. I Have checked before uninstalling path variables and i haven't seen mine that should be in.
I couldn't modify it either so I just reinstalled it.

php execute a python script from another directory

I have a PHP script that calls a Python script (with arguments):
<?php
$UPLOAD_DIR = 'tmp';
$AUDIOSPLIT = "../audiotranscri/scripts/audiospliter.py";
// This also fails using a symlink in the same dir
//$AUDIOSPLIT = "spliter";
$media_path = "tmp/media.mp3";
$subtitles_path = "tmp/mediasub.ass";
$cmd = "python3 ".$AUDIOSPLIT." ".$media_path." ".$subtitles_path." ".$UPLOAD_DIR;
echo($cmd);
system($cmd,$returnv);
echo($returnv);
?>
It works when i run this from a bash terminal
$ php7.2 dummy.php
But fails when call it from a website (Apache2 with PHP). Why ?
N.B: I am sure Apache and PHP are running OK since phpinfo() works perfectly. Versions are PHP 7.2.15, ubuntu 18.04.1, Apache 2.4.29.
Consider trying one of these:
use full path for your program as PATH might not be set when using system() - change "python3 " to "/usr/bin/python3 ", or wherever your python3 is.
Using another function, exec(), shell_exec(), passthrough()
Check if your web server allows you to run given functions when running through http, check in your php.ini, or check with php script accessed through http
<?php
$function_name = "system";
if ( function_exists($function_name) ) {
echo "$function_name is enabled";
}
else {
echo "$function_name is not enabled";
}

Execution of DalekJS with PHP does not work

I use the testing framework DalekJS to test the user interface. To execute my testing script mytest.js I type into the shell:
cd /Applications/XAMPP/xamppfiles/htdocs/tests
dalek mytest.js
and it works fine. Now I would like to execute the same script with PHP. My code:
<?php
chdir('/Applications/XAMPP/xamppfiles/htdocs/tests');
$command = 'dalek mytest.js';
exec($command, $return, $return_var);
var_dump($return);
var_dump($return_var);
Running my PHP-script in browser, it prints:
array(0) { } int(127)
The DalekJS script generates a screenshot when executing in shell but running with PHP it does not happen anything. I have also tried shell_exec(), system() and passthru() without success.
Do you have any idea why the PHP script does not work?
Calling dalek from PHP works fine for me. Is it possible your PHP process is running with a different environment (containing PATH, amongst other things) that your user? Maybe the apache user or some such?
<?php
// change current working directory of the current PHP process,
// this will subsequently change the initial CWD of exec()
$whereMyTestsAre = __DIR__;
chdir($whereMyTestsAre);
// locate dalek
$dalek = exec('which dalek');
// abort if there is no dalek,
// you may want to check PATH or supply the full path yourself
if (!$dalek) {
echo "could not find dalek executable, please check your path";
$PATH = exec('echo $PATH');
echo '$PATH is ', $PATH, "\n";
exit(1);
}
// relative to $whereMyTestsAre
// exec() blocks until the child process (dalek) exits
exec('dalek mytest.js');

PHP file execution

Hey, I'm trying to use PHP to execute a shell command which will run remotely run a server on my box. Here is my PHP Code:
if ($key == "test") { echo "<font color='green'>Key is valid. Server satrted.</font>";
$start = system('cd /root/st/; ls;');
}
The problem is, the ls command runs from the same directory as the web server, which returns all of the files from /var/www/html instead of /root/st/. I have also tried the chdir command to no avail. Anyone know how you would get the directory to change so that the command could be run from a specified directory? Thanks.
Does the user that PHP is running as (eg, the user invoking the CLI script) have permission to read the directory? If you're going into /root/ but aren't root, you'd need to either add cd to sudoers for the current user, or choose another directory.
Edit: note that adding cd to sudoers is not even remotely okay for anything other than a local, you-only script. :)
There are two ways I would approach this.
1: use proper unix commands, and see if they work. IE:
if ($key == "test") { echo "<font color='green'>Key is valid. Server satrted.</font>";
$start = system('ls /root/st/');
}
2: Make it run a script on the system, that can go outside the webserver's chroot.
if ($key == "test") { echo "<font color='green'>Key is valid. Server satrted.</font>";
$start = system('server.sh');
}
and server.sh is
#!/bin/bash
cd /root/st
ls
PHP has a chdir() function. Not sure if it applies to exec/system calls, but worth a try.
Store the location in a variable, say $loc = '/root/st' and then do ls $loc in your code. Hope this helps.
Your problem is not the directory the script is running in (or more precisely the current working directory of the user running the script), but that cd /root/st/ will fail on any reasonable configured UNIX/Linux system. /root is usually owned by root and can't be accessed by any other user.
Using you snippet this will silently fail because you unconditionally chained the cd and the ls commands with a semicolon instead of &&.

run php script only by cron

I know how to run a script with a cron, but what I need is to be able to run my script only by a cron.
Thank you!
You should keep this script outside of the public folder. Also, set appropriate permissions to the file so public users can not execute the script.
Put below code snippet to the top of your script.
if(php_sapi_name() !== 'cli'){
die('Can only be executed via CLI');
}
Note that you need to use the full path to the PHP executable when you setup your cron job.
Ex : /usr/local/bin/php (Your path may be differ from this)
As explained in this duplicate thread:
PHP & cron: security issues
You should keep this file outside of public_html.
Sometimes, though, this is not possible. My mind went to Moodle, where a similar feature exists. This is what they do.
From cron.php:
...
/// The current directory in PHP version 4.3.0 and above isn't necessarily the
/// directory of the script when run from the command line. The require_once()
/// would fail, so we'll have to chdir()
if (!isset($_SERVER['REMOTE_ADDR']) && isset($_SERVER['argv'][0])) {
chdir(dirname($_SERVER['argv'][0]));
}
...
/// check if execution allowed
if (isset($_SERVER['REMOTE_ADDR'])) { // if the script is accessed via the web.
if (!empty($CFG->cronclionly)) {
// This script can only be run via the cli.
print_error('cronerrorclionly', 'admin');
exit;
}
// This script is being called via the web, so check the password if there is one.
if (!empty($CFG->cronremotepassword)) {
$pass = optional_param('password', '', PARAM_RAW);
if($pass != $CFG->cronremotepassword) {
// wrong password.
print_error('cronerrorpassword', 'admin');
exit;
}
}
}
...
You need a PHP CLI/CGI executable for that. Assuming that the php program is located at /usr/local/bin/php, you can use:
/usr/local/bin/php /path/to/your/script.php
See also: http://nl.php.net/manual/en/features.commandline.usage.php
Please add this script at the top of your PHP file:
$isCLI = ( php_sapi_name() == 'cli' );
if( !$isCLI )
die("Sorry! Cannot run in a browser! This script is set to run via cron job");
and then if you try to run the PHP file via the browser, you cannot run it. This error message will be displayed. But at the same time, it can be run via a cron job.
Try to grant execute permissions only for the cron daemon user, maybe with that you get what you want.
Regards!

Categories