Cron Script Doesn't Work in Server Side - php

i have some cron files. And it was in under httpdocs. But i decided to move under cron folder. And i change the script.
config.php to ../config.php
When i call script from browser every thing works fine. But when i call from ssh i got en error undefined index : SERVER_NAME
I couldn't run cronjob. What can i do that ?
stock.php file
include_once '../config.php';
require_once CLASS_PATH.'class.product.php';
include_once INC_PATH.'functions.php';
....
config.php file
if ( !defined('ABSPATH') ) {
define('ABSPATH', dirname(__FILE__).'/');
}
define('PROTOCOL',(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') ? 'https' : 'http');
define('HOST', PROTOCOL.'://'.$_SERVER['SERVER_NAME']);
define('CLASS_PATH',ABSPATH.'includes/class/');
define('INC_PATH',ABSPATH.'includes/');
//if (isset($_SERVER['SERVER_NAME'])){
define('PRODUCT_IMG_PATH', 'images/product/');
//}
define('HEAD_META',ABSPATH.'view/head-meta.php');
define('NAVBAR', ABSPATH.'view/navbar.php');
define('HEADER', ABSPATH.'view/header.php');
define('FOOTER', ABSPATH.'view/footer.php');

The reason is that when you are running through ssh or command line you are in CLI mode, therefore none of those CGI variables can be used. It's recommended to use getenv() command instead which supports some of defined variables in CLI mode. However you need to configure and define them in you php.ini
You may need to look at Command line usage documentation for more details

How are you running it from cron? It seems that the server variables aren't being found when you run from terminal - which would make sense if you were php-running the file on the server. The SERVER-variables in php are set by the webserver - i.e. what answers a request over port 80 to the files in a specific location.
Here's php's documentation on server variables.
http://www.php.net/manual/en/reserved.variables.server.php

You web server is the one who fills the php $_SERVER array. I quote from the manual (http://www.php.net/manual/en/reserved.variables.server.php):
The entries in this array are created by the web server. There is no
guarantee that every web server will provide any of these; servers may
omit some, or provide others not listed here.
Obviously, if you call your script from the command line, there's no web servers to fill the $_SERVER array, and that's the reason of your problem.
To solve it, you can modify your config.php to load predefined values to the variables you need in case they don't exist. It would be something like this for every undef var:
if (!isset($_SERVER['SERVER_NAME'])) $_SERVER['SERVER_NAME']="localhost";

Related

Cron is sending empty array into my database

I am running a file that reads a large json file and then saves the content to database.
When I am running the file directly, it saves the data
But when I am trying to run it via cron job, it is saving null into database.
Here is my code
include('conn.php');
$file = "https://api.binance.com/api/v1/ticker/allPrices";
$json = file_get_contents($file);
updatePrice();
function updatePrice(){
global $con;
global $price;
$sql="INSERT INTO table(price) VALUES('$price')";
if(mysqli_query($con,$sql)){
echo "price updated";
}}?>
Thanks in advance!
Ensure that the value of location of the file is absolute rather than relative path. Cron job is using another id (usually root) so you need to explicitly use /home/userid/path/to/file.txt rather than ./file.txt.
Hope this helps. Thanks.
Edited: This also applies to your function file_get_contents.
Enable error reporting on your script and take a look for warnings or errors.
Check if allow_url_fopen is enabled for cli (some systems have separate .ini files for cli and web). You can do php --info to check which file is used on the cli.
I strongly recommend not using file_get_contents(), because it doesn't handles redirects or delays in response. Try cURL instead: http://www.php.net/manual/en/ref.curl.php

How to execute php in an external file

Why doesn't this work?
// File hosted on `example.com`
// db-con.php
<?php
define("DB_HOST" , "host");
define("DB_NAME" , "name");
define("DB_USER" , "user");
define("DB_PASS" , "pass");
-
// File hosted on `another-example.com`
// index.php
<?php
include 'http://example.com/db-con.php';
echo DB_HOST;
-
// output
Notice: Use of undefined constant DB_HOST - assumed 'DB_HOST' in C:\Users\Alex\Dropbox\Shared\Web\htdocs\BASE_TEMPLATE\index.php on line 14
Surely by including the external file, the php is run, and the constants are defined?
You are not including the file as you see it, but instead including the response of the remote web server when that file is requested.
That is, the remote web server sees a request for db-con.php, loads it up, executes the code (defining constants in its own local process) and returns the output to you (which is probably empty, as the code does not echo anything). Therefore the end result is the same as if you had included an empty file.
Update: dug up the reference from the manual:
If "URL fopen wrappers" are enabled in PHP (which they are in the
default configuration), you can specify the file to be included using
a URL (via HTTP or other supported wrapper - see Supported Protocols
and Wrappers for a list of protocols) instead of a local pathname. If
the target server interprets the target file as PHP code, variables
may be passed to the included file using a URL request string as used
with HTTP GET. This is not strictly speaking the same thing as
including the file and having it inherit the parent file's variable
scope; the script is actually being run on the remote server and the
result is then being included into the local script.
So how to do it?
Well, including code from a remote server is something you shouldn't really think of doing (although there are ways to make it happen, it's a really bad idea). In any case you won't be able to do it without the explicit cooperation of the remote server (otherwise anyone could include anyone else's configuration file and use get_defined_constants to get the passwords). And if you do it, anyone else would be able to follow the same steps and get hold of your passwords. You don't want that to happen.

session_start hangs

since a few hours our server hangs every time you do a session_start.
For testing purposes i created a script which looks like this:
<?php
session_start();
?>
Calling it from the console hangs and it can't even be stopped with ctrl-c, only kill -9 works. The same for calling it via Apache. /var/lib/php/session/ stays empty but permissions are absolutely fine, www can write and also has read permissions for all parent folders.
According to the admins there were no changes made on the server and there is no special code registered for sessions. The Server is CentOS 4 or 5 and yesterday everything was working perfectly. We rebooted the server and updated PHP, but nothing changed.
I've ran out of ideas, any suggestions?
UPDATE
We solved this problem by moving the project to another server, so while the problem still exists on one server there is no immediate need for a solution anymore.
I will keep the question open in case someone has an idea for others having a similar problem in the future, though.
There are many reasons for that, here are a few of them:
A. The session file could be opened exclusively.
When the file lock is not released properly for whatever reason, it is causing session_start() to hang infinitely on any future script executions.
Workaround: use session_set_save_handler() and make sure the write function uses fopen($file, 'w') instead of fopen($file, 'x')
B. Never use the following in your php.ini file (entropie file to "/dev/random"), this will cause your session_start() to hang:
<?php
ini_set("session.entropy_file", "/dev/random");
ini_set("session.entropy_length", "512");
?>
C.
session_start() needs a directory to write to.
You can get Apache plus PHP running in a normal user account. Apache will then of course have to listen to an other port than 80 (for instance, 8080).
Be sure to do the following things:
- create a temporary directory PREFIX/tmp
- put php.ini in PREFIX/lib
- edit php.ini and set session.save_path to the directory you just created
Otherwise, your scripts will seem to 'hang' on session_start().
If this helps:
In my scenario, session_start() was hanging at the same time I was using the XDebug debugger within PHPStorm, the IDE, on Windows. I found that there was a clear cause: Whenever I killed the debug session from within PHPStorm, the next time I tried to run a debug session, session_start() would hang.
The solution, if this is your scenario, is to make sure to restart Apache every time you kill an XDebug session within your IDE.
I had a weird issue with this myself.
I am using CentOS 5.5x64, PHP 5.2.10-1. A clean ANSI file in the root with nothing other than session_start() was hanging. The session was being written to disk and no errors were being thrown. It just hung.
I tried everything suggested by Thariama, and checked PHP compile settings etc.
My Fix:
yum reinstall php; /etc/init.d/httpd restart
Hope this helps someone.
To everyone complaining about the 30 seconds of downtime being unacceptable, this was an inexplicable issue on a brand new, clean OS install, NOT a running production machine. This solution should NOT be used in a production environment.
Ok I face the same problem on 2 PC, 1 is MAC mini XAMPP, 1 is Windows 10 Xampp.
Both is php spent infinity to run session_start(). Both PHP version is 7.x.x
I found that session files is lock to read and write. So that I added code to make PHP read session files and immediately unlock when done with
<?php
session_start([
'read_and_close' => true,
]);
?>
or
<?php
//For PHP 5.x
session_start();
session_write_close();
?>
After this PHP unlock session file => Problems solve
The problem: -
Iv experienced (and fixed) the problem where file based sessions hang the request, and database based sessions get out of sync by storing out of date session data (like storing each session save in the wrong order).
This is caused by any subsequent request that loads a session (simultaneous requests), like ajax, video embed where the video file is delivered via php script, dynamic resource file (like script or css) delivered via php script, etc.
In file based sessions file locking prevents session writing thus causing a deadlock between the simultaneous request threads.
In database based session the last request thread to complete becomes the most recent save, so for example a video delivery script will complete long after the page request and overwrite the since updated session with old session data.
The fix: -
If your ajax or resource delivery script doesnt need to use sessions then easiest to just remove session usage from it.
Otherwise you'd best make yourself a coffee and do the following: -
Write or employ a session handler (if not already doing so) as per http://www.php.net//manual/en/class.sessionhandler.php (many other examples available via google search).
In your session handler function write() prepend the code ...
// processes may declare their session as read only ...
if(!empty($_SESSION['no_session_write'])) {
unset($_SESSION['no_session_write']);
return true;
}
In your ajax or resource delivery php script add the code (after the session is started) ...
$_SESSION['no_session_write'] = true;
I realise this seems like a lot of stuffing around for what should be a tiny fix, but unfortunately if you need to have simultaneous requests each loading a session then it is required.
NOTE if your ajax or resource delivery script does actually need to write/save data, then you need to do it somewhere other than in the session, like database.
Just put session_write_close(); befor Session_start();
as below:
<?php
session_write_close();
session_start();
.....
?>
I don't know why, but changing this value in /etc/php/7.4/apache2/php.ini worked for me:
;session.save_path = "/var/lib/php/sessions"
session.save_path = "/tmp"
To throw another answer into the mix for those going bananas, I had a session_start() dying only in particular cases and scripts. The reason my session was dying was ultimately because I was storing a lot of data in them after a particularly intensive script, and ultimately the call to session_start() was exhausting the 'memory_limit' setting in php.ini.
After increasing 'memory_limit', those session_start() calls no longer killed my script.
For me, the problem seemed to originate from SeLinux. The needed command was chcon -R -t httpd_sys_content_t [www directory] to give access to the right directory.
See https://askubuntu.com/questions/451922/apache-access-denied-because-search-permissions-are-missing
If you use pgAdmin 4 this can happen as well.
If you have File > Preferences > SQL Editor > Options > "Auto Commit" disabled, and you just ran a query using the query tool but didn't manually commit, then session_start() will freeze.
Enable auto commit, or manually commit, or just close pgAdmin, and it will no longer freeze.
In my case it seems like it was the NFS Share that was locking the session , after restarting the NFS server and only enabled 1 node of web clients the sessions worked normally .
Yet another few cents that might help someone. In my case I was storing in $_SESSION complex data with several different class objects in them and session_start() couldn't handle the whole unserialization as not every class was loaded on session_start. The solution is my case was to serialize/jsonify data before saving it into the $_SESSION and reversing the process after I got the data out of session.

php access network path under windows

within PHP (XAMPP) installed on a Windows XP Computer Im trying to read a dir which exists on a local network server. Im using is_dir() to check whether it is a dir that I can read.
In Windows Explorer I type \\\server\dir and that dir is being shown.
When I map a network drive a can access it with z:\dir as well.
In PHP I have that script:
<?php if( is_dir($dir){ echo 'success' } ) ?>
For $dir I tried:
/server/dir
//server/dir
\server\dir
\\server\dir
\\\\server\\dir
and
z:\dir
z:\\dir
z:/dir
z://dir
But I never get success?
Any idea?
thx
I solved it by changing some stuff in the registry of the server as explained in the last answer of this discussion:
http://bugs.php.net/bug.php?id=25805
Thanks to VolkerK and Gumbo anyway!
I love stackoverflow and their great people who help you so incredibly fast!!
EDIT (taken from php.net):
The service has limited access to network resources, such as shares
and pipes, because it has no credentials and must connect using a null
session. The following registry key contains the NullSessionPipes and
NullSessionShares values, which are used to specify the pipes and
shares to which null sessions may connect:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Alternatively, you could add the REG_DWORD value
RestrictNullSessAccess to the key and set it to 0 to allow all null
sessions to access all pipes and shares created on that machine.`
add RestrictNullSessAccess=0 to your registery.
You probably let xampp install apache as service and run the php scripts trough this apache. And the apache service (running as localsystem) is not allowed to access the network the way your user account is.
A service that runs in the context of the LocalSystem account inherits the security context of the SCM. The user SID is created from the SECURITY_LOCAL_SYSTEM_RID value. The account is not associated with any logged-on user account.
This has several implications:
...
* The service presents the computer's credentials to remote servers.
...
You can test this by starting the apache as console application (apache_start.bat in the xampp directory should do that) and run the script again. You can use both forward and backward slashes in the unc path. I'd suggest using //server/share since php doesn't care about / in string literals.
<?php
$uncpath = '//server/dir';
$dh = opendir($uncpath);
echo "<pre>\n";
var_dump($dh, error_get_last());
echo "\n</pre>";
Try the file: URI scheme:
file://server/dir
file:///Z:/dir
The begin is always file://. The next path segment is the server. If it’s on your local machine, leave it blank (see second example). See also File URIs in Windows.
Yes, I know this is an old post, but I still found it, and if anyone else does...
On Windows, with newer servers, verify the SMB is installed and enabled on the target machine.

How to use the PHP built-in server with Windows Authentication (NTLM) to fill $_SERVER["LOGON_USER"]?

I have scripts that use the $_SERVER["LOGON_USER"] which is obtained on my servers through IIS authentication settings. I want this same variable to contain my domain\username when running locally, or at least to have a way to set it when I fire up the PHP built-in server on localhost.
How can I configure PHP on my machine to obtain and fill this variable the same way it does when running through IIS?
PS: I have seen this question, but the answer addresses $_ENV, not $_SERVER.
This is a workaround, if anyone has a better/proper solution (i.e. enabling NTLM), please post it as an answer and I'll accept it.
I was able to fill that variable using a router script. According to the docs, this script is run at the start of each HTTP request, so I use it to set this variable when running locally.
Also in my case, my environment had these two variables set, USERDOMAIN and USERNAME, so I used them to form the LOGON_USER server variable.
routerCredentials.php
<?php
$_SERVER["LOGON_USER"] = getenv("USERDOMAIN") . "\\" . getenv("USERNAME");
return false; // serve the requested resource as-is.
To use it, you just have to point to that file when you start the PHP built-in server:
php -S localhost:8000 "c:\somepath\routerCredentials.php"

Categories