hash comparison true when nothing as changed - php

I want to synchronize files between two servers.
The idea is to check if a file exists on the "local" server and if true, check if it the same as a remote server. If not, the update it.
If it doesn't exist, add it.
The code seems to work but always one file is changed, even when it hasn't and its a different one each time.
Is there an error or what is the reason?
if (file_exists($img)) {
$image_hashfile_remote = sha1_file($image_url[$urlIndex]);
$image_hashfile_local = sha1_file($img);
if ($image_hashfile_local == $image_hashfile_remote) {
$num_same++;
} else {
file_put_contents($img, file_get_contents($image_url[$urlIndex]));
echo "Image file as changed since last synchronization. " .$img . " updated. <br />";
echo $image_hashfile_local . " " .$image_hashfile_remote . "<br />";
$num_saved++;
}
} else {
file_put_contents($img, file_get_contents($image_url[$urlIndex]));
echo "New image file found. " . $img . " added. <br />";
$num_saved++;
}

Related

Cannot upload using php scripts

I have a script in php that is used to upload files to a server. It was working first but i dont know why its not working again. It shows no error but the file is not still uploaded to the directory that i assigned to hold all uploaded files. Here is the part that takes care of the upload:
<?php
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Uploaded: " . basename($_FILES["file"]["name"]) . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
//by default the size of the file is in bytes so u need to divide by 1024 in order to bring it to KB
echo "Temporarily stored in: " . $_FILES["file"]["tmp_name"] . "<br />";
$target="/file/" . basename($_FILES["file"]["name"]) . "<br />";
}
if(move_uploaded_file($_FILES["file"]["tmp_name"], $target))
{
echo "<h2>" . "The file has been stored on the server" . "<br />" . "<h2 />";
echo "New storage location is : " . '<a href="/public/files/" >' . $target . '</a>';
?>
<html>
<body>
<div align="right"><a href="/public/files/" >Uploaded files</a></div>
<br />
</body>
</html>
<?php
}
else
{
echo "<h2>" . "Error while saving the file to the server." . "<br />" . "File wont be found in the uploaded files directory" . "<br />" . "<h2 />";
echo "The error says: " . $_FILE["file"]["error"] . " What do we do now?" ;
echo"<pre>".print_r($_FILES,true)."</pre>";
?>
<?
/file/ is a directory in the root of your server's filesystem, which almost certainly doesn't exist. move_uploaded_file() works at the filesystem level and has absolutely NO awareness of your site's URI structure. You probably want something more like:
move_uploaded_file(...,. $_SERVER['DOCUMENT_ROOT'] . '/file/');
^^^^^^^^^^^^^^^^^^^^^^^^^^^---- add this
so that the file gets moved to a /file subdir of your site's root directory.

Replace uploaded document on confirm not working

My Requirement is as follows:
When user uploads a file i should check for "File already Exists", if file exists i must show confirm box if 'OK' i have to replace and if cancel the reverse.
This is my following code
if (file_exists($path . $documentName)) {
$msg = $documentName . " already exists. ";
?>
<script type="text/javascript">
var res = confirm('File already exists Do you want to replace?');
if (res == false) {
<?php
$msg = 'File Upload cancelled';
?>
} else {
<?php
if (move_uploaded_file($_FILES["document"]["tmp_name"], $path . $documentName)) {
$msg = $documentName . " File Replaced Successfully";
$successURL = $document_path . $documentName;
}
else
$msg = $documentName . "Upload Failed";
?>
}
</script>";
<?
}
My problem is even if i give cancel the file is getting replaced.
just let me know where I'm wrong or Is there any other approach?
Please help me to close this issue
Note:jquery Not allowed.
Your problem is that you mix javascript and PHP. The PHP-Code will be run on the server and generates the HTML-document. At this point, the file gets replaced already.
Then, this document (with the javascript-code inside) will then be send to the user and there the javascript-code is run. And in that moment, the user gets to see the confirmaion-dialog, even though the file already was replaced!
Take a look at the source-code that your php-code is generating and you will see what I mean.
A solution would be to add a checkbox to confirm overwriting files. Then after hitting the upload-/submit-button, your php-script would check if this box was checked and either replace the file or not.
#Gogul, honestly, this is not the right way to go. Better that you handle the file submission with an AJAX request which receives a response back from your server (either uploaded successfully, or file exists) which you handle appropriately. If presenting the user an option to replace the file, again handle that action with AJAX.
You can do AJAX request in raw JavaScript (jQuery not required) - see here: http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
You are mixing server side code with client side javascript. The solving of your problem is more complicated if you don't want the user to reupload the document:
Store the file in a temporary location under random filename. Output a yes/no form to the user, including the random filename and original filename.
If the user answers yes, move from temporary location to $path, else remove the file from temporary location.
Guys i came with with this following solution
upload
uploaddocument.php
$documentName = preg_replace('/[^a-zA-Z0-9.]/s', '_', $_FILES["document"]["name"]);
if (file_exists($path . $documentName)) {
move_uploaded_file($_FILES["document"]["tmp_name"], "F:\\Content\\enews_files\\temp\\" . $documentName);
$msg = $documentName . " already exists. <a href='confirm.php?confirm=1&filename=" . $documentName . "&language=" . $lang . "'>Replace</a>||<a href='confirm.php?confirm=0&filename=" . $documentName . "'>Cancel</a>";
} else {
if (move_uploaded_file($_FILES["document"]["tmp_name"], $path . $documentName)) {
$msg = $documentName . " Upload Success";
$successURL = $document_path . $lang . '/' . $documentName;
}
else
$msg = $documentName . " Upload Failed";
}
confirm.php
include("config_enews.php");
$lang = $_GET['language'];
$path = "F:\\Content\\enews_files\\" . $lang . "\\";
//$path = "D:\\test\\test\\" . $lang . "\\";
$documentName = preg_replace('/[^a-zA-Z0-9.]/s', '_', $_GET["filename"]);
if ($_GET['confirm'] == 1) {
//echo sys_get_temp_dir();die;
if (copy("F:\\Content\\enews_files\\temp\\" . $_GET["filename"], $path . $documentName)) {
unlink("F:\\Content\\enews_files\\temp\\" . $_GET["filename"]);
header("Location: uploaddocument.php?message=success&fname=$documentName&lang=$lang");
} else {
echo $res = move_uploaded_file($_GET["tempname"], $path . $documentName);
echo $msg = $documentName . " Upload Failed";
header("Location: uploaddocument.php?message=failed&fname=$documentName");
}
} else {
unlink("F:\\Content\\enews_files\\temp\\" . $_GET["filename"]);
header("Location: uploaddocument.php?message=cancelled&fname=$documentName");
}
I got this spark from #Marek. If any one has better solution kindly provide.
I don't have enough reputations to vote your answers sorry.
Thank you so much for all your support.

File flushed when attempting to update contents

I have written a very simple page counter and a logging script that increments a counter stored in a file and logs information about the client's operating system and which browser they use. It's a simple spare time project I've been working on, and as such it is extremely rudimentary, writing the counter and the logged information in a designated folder for each page on the site, in a new file for each day.
The thing is, I recently used blitz.io to test my site, and when I ran a "Rush" of 250 requests per second, the counters and the logs were completely flushed, except for the very last query.
I'm not perfectly sure what happened, but I suspect something along the lines of PHP not properly finishing up the previous query before taking on the next one.
I use file_get_contents()/file_put_contents() for the both of them, instead of file(). Would changing to file() solve the problem?
Here's the counter:
$filename = '.' . $_SERVER['PHP_SELF'];
$counterpath = '/Websites/inc/logs/counters/total/' . getCurrentFileName() . '-counter.txt';
$globalcounter = '/Websites/inc/logs/counters/total/global-counter.txt';
if (file_exists($counterpath)) {
$hit_count = file_get_contents($counterpath);
$hit_count++;
file_put_contents($counterpath,$hit_count);
}
else {
$hit_count = "1";
file_put_contents($counterpath, $hit_count);
}
And here's the logger:
$logdatefolder = '/Websites/inc/logs/ip/' . date('Y-m-d',$_SERVER['REQUEST_TIME_FLOAT']);
$logfile = $logdatefolder . "/" . getCurrentFileName() . '-iplog.html';
$ua = getbrowser();
if (false == (file_exists($logdatefolder))) {
mkdir($logdatefolder);
}
function checkRef() {
if (!isset($_SERVER['HTTP_REFERER'])) {
//If not isset -> set with dummy value
$_SERVER['HTTP_REFERER'] = 'N/A';
}
return $_SERVER['HTTP_REFERER'];
}
/* Main logger */
$logheader = "<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en-US\"><head><title>" . getCurrentFileName() . " log</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head><body>";
$logentry = date("Y-m-d, H:i:s, O T") . ":" .
"<br />- Requesting: http://giphtbase.org" . $_SERVER['REQUEST_URI'] .
"<br />- Arriving from: " . checkRef() .
"<br />- Browser: " . $ua['browser'] .
"<br />- Full browser name: " . $ua['name'] .
"<br />- Operating system: " . $ua['platform'] .
"<br />- Full user agent: " . $ua['userAgent'] .
"<br />";
$logfooter = "<!-- Bottom --></body></html>";
if (file_exists($logfile)) {
$logPage = file_get_contents($logfile);
$logContents = str_replace("<!-- Bottom --></body></html>","",$logPage);
file_put_contents($logfile, $logContents . $logentry . $logfooter);
}
elseif (false == (file_exists($logfile))) {
file_put_contents($logfile, $logheader . $logentry . $logfooter);
}
You should use the FILE_APPEND flag in your file_put_contents() otherwise you will only ever see the last entry:
file_put_contents($logfile, $logContents . $logentry . $logfooter, FILE_APPEND);
As for the counter, it looks like the file is trying to be written to too many times by different threads, causing it to be inaccessible. You should either use a database, or create a file_lock, or create temporary files and run a cronjob to do the math.

Can't find uploaded files after PHP image upload

I'm uploading files from an iPhone app to PHP using the following code:
<?php
if ($_FILES["media"]["error"] > 0) {
echo "Error: " . $_FILES["media"]["error"] . "<br />";
} else {
echo "Upload: " . $_FILES["media"]["name"];
echo "Type: " . $_FILES["media"]["type"];
echo "Size: " . ($_FILES["media"]["size"] / 1024);
echo "Stored in: " . $_FILES["media"]["tmp_name"];
if (file_exists("uploads/" . $_FILES["media"]["name"])) {
echo $_FILES["media"]["name"] . " already exists. ";
} else {
move_uploaded_file($_FILES["media"]["tmp_name"],
"uploads/" . $_FILES["media"]["name"]);
echo "Stored in: " . "uploads/" . $_FILES["media"]["name"];
}
}
?>
Afterwards, I get the success message saying "uploads/2542543.jpg" - but I can't seem to find where the image is actually stored. Is the filepath relative to the php file (which is in php - and has an uploads folder) or is it absolute from the root??
EDIT: Looks like the file should have ended up in php/uploads/filename.jpg - but it doesn't appear to be making it. I don't quite understand why - anyone have any idea?
This is an absolute path from the root
/uploads/2543.jpg
This is a relative path from your PHP document
uploads/2543.jpg
So you're working with a relative path (note the missing / at the start)
This is defined in php.ini using the upload_tmp_dir directive. If that's not set, it uses the system default, which you can figure out using sys_get_temp_dir. I believe it defaults to /tmp on Linux, and C:\Windows\Temp\ on Windows.

I have this broken php upload script

I have this script for uploading a image and content from a form, it works in one project but not the other. I have spent a good few hours trying to debug it, I am hoping someone could point out the issue I might be having. Where there are comments is where I have tried to debug. The first error I got was the "echo invalid file" at the beginning of the last comment. With these specific areas commented out the upload name and type that I am supposed to be grabbing from the form is not being echoed, I am thinking this is where the error is occurring, but can't quite seem to find it. Thanks.
<?php
include("../includes/connect.php");
/*
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 2000000))
{
*/
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
/* GRAB FORM DATA */
$title = $_POST['title'];
$date = $_POST['date'];
$content = $_POST['content'];
$imageName1 = $_FILES["file"]["name"];
echo $title;
echo "<br/>";
echo $date;
echo "<br/>";
echo $content;
echo "<br/>";
echo $imageName1;
$sql = "INSERT INTO blog (title,date,content,image)VALUES(
\"$title\",
\"$date\",
\"$content\",
\"$imageName1\"
)";
$results = mysql_query($sql)or die(mysql_error());
echo "<br/>";
if (file_exists("../images/blog/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " already exists. ";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"],
"../images/blog/" . $_FILES["file"]["name"]);
echo "Stored in: " . "../images/blog/" . $_FILES["file"]["name"];
}
}
/*
}
else
{
echo "Invalid file" . "<br/>";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
}
*/
//lets create a thumbnail of this uploaded image.
/*
$fileName = $_FILES["file"]["name"];
createThumb($fileName,310,"../images/blog/thumbs/");
function createThumb($thisFileName, $thisThumbWidth, $thisThumbDest){
$thisOriginalFilePath = "../images/blog/". $thisFileName;
list($width, $height) = getimagesize($thisOriginalFilePath);
$imgRatio =$width/$height;
$thisThumbHeight = $thisThumbWidth/$imgRatio;
$thumb = imagecreatetruecolor($thisThumbWidth,$thisThumbHeight);
$source = imagecreatefromjpeg($thisOriginalFilePath);
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $thisThumbWidth,$thisThumbHeight, $width, $height);
$newFileName = $thisThumbDest.$thisFileName;
imagejpeg($thumb,$newFileName, 80);
echo "<p><img src=\"$newFileName\" /></p>";
//header("location: http://www.google.ca");
}
*/
?>
Perhaps you forgot to add enctype="multipart/form-data" method="post" to your HTML form, or have no <input type="file" name="file" id="file" value=""/> in your HTML.
Here's some problems with your script:
The 'error' value in the $_FILES array is not just a boolean, it will tell you if an upload succeeded, or why it failed. The error codes are defined here.
The 'type' value is supplied by the remote client. It's NOT determined by the web server or PHP. As such, doing mime-type verification based on that value is a major hole: it's trivial to forge the supplied type value. Best to use a server-side method, like fileinfo, to determine the actual mime type.
You blindly insert the form data into your insertion query, which leaves you wide open to SQL injection attacks. At least pass the data through mysql_real_escape_string() before building your query, or better yet, use PDO and parameterized queries
You're storing the files with the original client-provided name. You at least check if the filename's already in use, preventing upload collisions/overwriting, but there's also the case where the client's operating system/file system allows characters in filenames that the server's OS/FS do not, which could lead to subtle file "vanished" bugs, or overwriting entirely different files because the invalid characters were filtered out or translated to something else. Since you're using a database to store information about the upload, you can store the original filename in that table, and use the table's primary key (an auto_increment int, right?) as the filename.
Not really a problem, but in terms of efficiency, there's no need to use getimagesize() in your thumb creation function. GD has imagesx() and imagesy() which get the pixel size from a GD image handle. getimagesize() is independent of GD, so you're opening and parsing the source image twice. Again, it's not really a problem, but on a busy site, opening the image only once could be a decent cpu time and memory usage savings.
The error was in the html form file, I had added a name="something" beside the method="post" and enctype="multi/form-data" obviously this was not liked. Thanks RC for pointing me in the right direction. I am not quite sure why I did this.
$_FILES["file"]["error"] is not just a flag.
It has error codes.
Explained in the manual

Categories