PHP Header in CRON Job not working - php

I am using this code header('Location: http://example.com/test.php?number='.$requestsDone.'');
But looks like it is not working, what is wrong here?
Let me know, if you need more information.

Producing a header in a command line script doesn't make any sense. The header is part of the HTTP protocol, there is no HTTP involved when the script is executed using the CLI version of PHP.
Accordingly, the header() function is not implemented in the CLI version of PHP. It exists, but it doesn't produce any output.
Also, the superglobals that contain information extracted from the HTTP request ($_GET[], $_POST[], $_REQUEST[], $_FILES[], $_COOKIE[] etc) exist but they are empty.
In order to pass arguments to a script using the command line, use the $argc and $argv[] variables.

Related

Passing variables from PHP to python

I have a python script. When I run the script from the command line as:
python upgrade.py arg1 arg2
The script runs successfully.
Now I am trying to pass the same variables via PHP code using:
passthru("python upgrade_device.py $arg1 $arg2");
The script does not execute.
I am accepting the arguments using:
sys.argv
The arguments are passed correctly
I have tested using print
This is specific command where the execution fails:
child=pexpect.spawn('ssh admin#%s'%ip_addr)
ip_addr is one of the arguments passed from PHP. Right below this command I am ip_addr so as to find what value is passed to the command. and the value is as expected.
I have the ip_addr variable stored correctly.
I have even type casted it to string so that should not be problem.
In general, is there a difference of format in passing variables from the command line and passing from PHP
For my understanding i think passing it through shell and php is the same, i can't be sure for 100% but that what i know from experience.
For your case if you have verified with print that it's the right string to pass (mean take the output and test it in the terminal if it work) if it work, than verify if the python script file is in the same directory as the php script file, because the shell will be opened at the current php script path. And so the shell command should respect that. For example let assume php script file is in the root "/", and python script file is in "/myPythonScripts/imageProccessing/" then when you execute something like "python myPyScript.py 646545645" for example, in this example in php you should execut "python ./myPythonScripts/imageProccessing/myPyScript.py 646545645", as i said the shell is launched on the php script path.
Now if that's not the problem, then try escaping the string first, with escapeshellcmd(). And see what it give. There is characters that are not supported by the shell, or that have a certain signification and parsed by the shell differently. make sure none of them is passed as argument.
In case none of the above is helpful try to use execshell() instead, and see what it give. Too probable that will not make a difference.
Edit: In case nothing helped, try to change just a bit the way of the exchange is done, and use the way it's done in this response using json https://stackoverflow.com/a/14048046/7668448 (it's a kind of more convenient)
Please if any of that solved the problem, precise in a response which one was! I hope it will help. Also if it's not your case it may be useful for other persons in the future. Think also about giving the solution when you do! (i also personally interested too)

curl not executing properly when invoked by php

So I want to execute a bash command from PHP on my web server. I can do this using shell_exec. However, one of the commands I want to execute is curl. I use it to send a .wav file to another server and record its response. But when invoked from PHP, curl doesn't work.
I reduced the error to the following small example. I have a script named php_script.php which contains:
<?php
$ver=shell_exec("curl -F file=#uploads/2013-7-24-17-31-43-29097-flash.wav http://otherserver");
echo $ver
The curious thing is that when I run this php script from command line using php php_script.php, the result I get is
Status: 500 Internal Server Error
Content-type: text/html
However, if I run curl -F file=#uploads/2013-7-24-17-31-43-29097-flash.wav http://otherserver directly, I get the response I was expecting:
verdict = authentic
(Edit:) I should probably mention that if I put some bash code inside the shell_exec argument which does not contain curl, the bash command executes fine. For example, changing the line to $ver = shell_exec("echo hello > world"); puts the word "hello" into the file "world" (provided it exists and is writable). (End edit.)
Something is blocking the execution of curl when it is invoked from PHP. I thought this might be PHP's running in safe mode, but I found no indication of this in php.ini. (Is there a way to test this to make 100% sure?) What's blocking curl and, more importantly, how can I bypass or disable this block?
(And yes, I realize PHP has a curl library. However, I prefer to use commands I can run from the command line as well, for debugging purposes.)
cheers,
Alan
The reason is the administrative privileges when you run the command directly you are running it as root and thus the command gets executed. But, when you run the command through PHP it runs as an user. By, default user has not the privileges to run the shell_exec commands.
You have to change the settings of shell_exec through CPanel/Apache config file. But, it is not recommended to provide the shell_exec access to the user as it help hackers to attack on server and thus, proper care should be taken.
It would be more appropriate to use the curl library provided in PHP.

Cronjob doens't understand the code to execute?

I have set up a cronjob which updates a bunch of contracts in a certain system. When I run the PHP-script in a browser it all works fine, but when the cronjob has to do the trick it fails. I'm kinda stuck on this one since I don't have a lot of experience with cronjobs (heck.. I can only set them up in DirectAdmin).
My PHP scripts has some includes to some classes, these includes work properly (i've tested it by sending mails to myself line by line). When the base-classes are included I have a class which handles autoloading. When I do something like Class::GetInstance() it fails.
My cronjob looks like:
* * * * * /usr/local/bin/php /home/username/domains/domain/public_html/path/to/script.php
What can I do to fix this? Perhaps not run it via php, but by a browser or something? I'm sorry if this is a stupid question, but I don't know this ;)
Remeber that when PHP is executed on CLI with /usr/local/bin/php you do not have the $_SERVER variable setted properly! I had that problem too because my script had to use $_SERVER['DOCUMENT_ROOT']. As said, try to run it in a normal shell to see if it works. Alternatively you can change your cronjob command to:
wget -q http://yourdomain.com/path/to/script.php
Usually this works well because it is just identical to fetch that URL from a normal browser.
wget man page here: http://linux.die.net/man/1/wget
You can't always call the php file directly that expects to be called via HTTP. Judging from path, it's a part of website, which is normally executed by browser, hence I'ld set the cronjob up to not to be directly called by php-cli, but rather by doing a curl request to the website's URL.
"it fails" is not the problem description one can call a suffucient one.
add this line in your crontab file
MAILTO=your#mail
and run your jobs.
You will get the script output and be able either to correct your code or ask a sensible question.
You may also redirect stdout and stderr to a log file

How to distinguish command-line and web-server invocation? [duplicate]

This question already has answers here:
Closed 14 years ago.
Is there a way to distinguish if a script was invoked from the command line or by the web server?
(See What is the canonical way to determine commandline vs. http execution of a PHP script? for best answer and more detailed discussion - didn't find that one before posting)
I have a (non-production) server with Apache 2.2.10 and PHP 5.2.6. On it, in a web-accessible directory is my PHP script, maintenance_tasks.php. I would like to invoke this script from the command line or through a HTTP request (by opening in a browser). Is there some variable that allows me to reliably determine how script is invoked?
(I already tackled the issues of different views for each type of invocation and HTTP response timeout, just looking for a way of telling the two invocation types apart)
I'll be trying different things and add my findings below.
Duplicate: What is the canonical way to determine commandline vs. http execution of a PHP script?
If called from command line, the server variable HTTP_USER_AGENT is not set. I use this constant to define, whether the script is called from command line or not:
define("CLI", !isset($_SERVER['HTTP_USER_AGENT']));
UPDATE: Since this answer is still marked as the 'correct' one, I'd like to revise my statement - relying on the "User-Agent" header can be problematic, since it's a user-defined value.
Please use php_sapi_name() == 'cli' or PHP_SAPI == 'cli', as suggested by Eugene/cam8001 in the comments.
Thanks for pointing this out!
I've compared the $_SERVER superglobal in both invocations. It seems that $_SERVER['argc'] (i.e. number of arguments passed to the script) is only set when running from shell/command line:
<?php
if (isset($_SERVER['argc'])) {
define('CLI', true);
} else {
define('CLI', false);
}
That seems to work both on Linux and Windows hosts. (First I thought about checking for some of the environment variables, but those are different for every operating system. Also, all the $_SERVER['HTTP_*'] headers are missing in the CLI version, but I'm not sure if that's reliable enough.)

Can I 'drop' a PHP request without replying?

I am not completely sure that this is possible from within PHP or even the HTTP protocol in depth. Is it possible to receive PHP script to run when it is requested but then the script drops the connection? Without replying?
Hopefully my question makes sense.
(I am using Apache)
When you serve php through Apache, there will always be a http response. Calling exit will just stop php from processing - not stop Apache. The proper thing to do in your case, is probably to send a http response-code other than 200 (OK). For example 404 or 500. Check the specs to find the one that applies to your situation.
You send a http response from within php, using:
<?php
header("HTTP/1.0 404 Not Found");
exit;
If you don't want to send any data at all, use a sleep in a loop. Eventually the client end will time out and close the connection.
You can use exit() or die() in the script to stop script execution, would that do what you want?
Why would you want to do this? Surely you should be sending some kind of HTTP error code instead?
That depends on the software you use. Apache for example terminates any scripts as soon as the connection closes.

Categories