Issue
I am trying to run a cron job on a shared host. The cron job is working and the script is running and entering data to a table but the problem is when it reaches the point where it must save an image, it is not doing it. I need please to know why?
To tell you what I found out: -I found out that for a script to run through a cron job, you must put the connection of the database in the same file and not include it
So here is my script with credentials being hidden:
$start_time = microtime(true);
define("DB_HOST", "*******");
define("DB_USER", "*******");
define("DB_PASS", "*******");
define("DB_NAME", "*******");
$connection = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
//define('SITE_ROOT', $_SERVER['DOCUMENT_ROOT']);
//include "create_thumbnail.php";
// the news feeds table name is feeds_list
$query_count = "SELECT COUNT(*) FROM youtube_channels_feed_list WHERE active = 1";
$result_count = mysqli_query($connection, $query_count);
$count = mysqli_fetch_array($result_count);
$count_shift = array_shift($count);
if($count_shift > 0) {
$query_fetch = "SELECT * FROM youtube_channels_feed_list WHERE active = 1";
$result_fetch = mysqli_query($connection, $query_fetch);
while($row = mysqli_fetch_assoc($result_fetch)) {
$feed_id = $row["id"];
$feed_name = strtolower($row["feed_name"]);
$feed_url = $row["feed_url"];
$feed_region = $row["feed_region"];
$feed_length = $row["feed_length"];
$subject_id = $row["subject_id"];
$feed_source_url = $row["feed_source_url"];
$url = $feed_url;
$xml = simplexml_load_file($url);
if($xml === false){
//echo "Operation failed<br/><br/>";
} else {
$count = 0;
for($i = 0; $i < $feed_length; $i++) {
$count++;
//echo "<br/><b><i>".$feed_name.": ------</i></b><br/><br/>";
//echo "Feed Length is: ".$feed_length."<br/><br/>";
// because item 0 is about the site and not news
$title = $xml->entry[$i]->title;
$title = str_replace("'", "'", $title);
$title = str_replace('"', """, $title);
$link = $xml->entry[$i]->link->attributes()['href'];
$pubDate = $xml->entry[$i]->published;
$pubDate = strtotime($pubDate);
$insert_date = time();
$image_outer_link = $xml->entry[$i]->children( 'media', True )->group->children( 'media', True )->thumbnail->attributes()['url'];
//echo $image_outer_link . "<br/>";
// for ignore to work we must make the title field in table UNIQUE
$query1 = "INSERT IGNORE INTO youtube_videos_testing (title, link, pubDate, channel_feed_id, subject_id, insert_date) VALUES('$title', '$link', $pubDate, $feed_id, $subject_id, $insert_date)";
if($result = mysqli_query($connection, $query1)){
$the_last_inserted_id = mysqli_insert_id($connection);
echo "last inserted id: " . $the_last_inserted_id . "<br>";
$new_image_link1 = "video-" . $the_last_inserted_id . ".jpg";
$new_image_link_thumb = "youtube-video-thumb-" . $the_last_inserted_id . ".jpg";
$query2 = "UPDATE youtube_videos_testing SET image = '$new_image_link_thumb' WHERE id = " . $the_last_inserted_id;
//echo $query2. "<br>";
$result2 = mysqli_query($connection, $query2);
$affected_rows = mysqli_affected_rows($connection);
//echo "affected_rows = " . $affected_rows;
if($affected_rows > 0) {
$query3 = "UPDATE youtube_videos_testing SET updated = 1 WHERE id = " . $the_last_inserted_id;
//echo $query2. "<br>";
$result3 = mysqli_query($connection, $query3);
// HERE IS WHERE THE PROBLEM IS HAPPENING
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/admin/uploads/youtube_videos_testing/" . $new_image_link1;
echo $target_path . "<br>";
// Open the file to get existing content
$data = file_get_contents($image_outer_link);
// Write the contents back to a new file
file_put_contents($target_path, $data);
}
}
}
//echo "Count: " . $count . "<br>";
}
}
} else {
//echo "database is empty";
}
// These lines should be placed at the end of the script to get the script running time
// End clock time in seconds
$end_time = microtime(true);
// Calculate script execution time
$execution_time = ($end_time - $start_time);
echo " Execution time of script = ".$execution_time." sec";
Solution
Chances are that the cron job runs either as a different user or with a different home directory than what you're expecting.
Another usual source of trouble is that with crontab scripts, the $_SERVER array is not populated because they're not being run by a web server at all. You don't have DOCUMENT_ROOT, and so on.
Since you seem able to write to the database, try saving in a text field in a debug table the result from the get_current_user()
and getcwd()
commands.
Alternatively, if the first command in your script is
chdir(__DIR__);
this will ensure that the script is running from the directory in which it originates.
If your script resides in your DOCUMENT_ROOT, then you can use __DIR__
instead of $_SERVER['DOCUMENT_ROOT']
. Or you can add at the top
if (!isset($_SERVER)) {
$_SERVER = array();
}
$_SERVER['DOCUMENT_ROOT'] = __DIR__;
to quickly fix things.
Another solution, when available, is to have cron call your script as a Web page using lynx or curl:
curl -sk http://yourwebserver.com/path/to/script.php > /dev/null 2>&1
It is usually better to save the output to a log file to investigate possible errors (so, ">> /path/to/var/www/html/logs/debug.log" instead of "> /dev/null" -- notice the two >'s to append to a log rather than rewriting it each time).
Answered By - LSerni