Downloading a 2MB File in PHP - php

I'm writing a function that updates a database file every 30 days. It works great for small files, but for files over 200K or so, it just downloads a partial file. How can I make this work with files up to 2MB?
function lsmi_geoip_update() {
$dir = dirname( __FILE__ );
$localfilev4 = $dir . '/data/GeoIPv4.dat';
$localfilev6 = $dir . '/data/GeoIPv6.dat';
if ( file_exists( $localfilev4 ) ) {
rename($dir . '/data/GeoIPv4.dat', $dir . '/data/OLD_GeoIPv4.dat');
$newfilev4 = file_get_contents('http://gdriv.es/geoipupdate/GeoIPv4.dat');
file_put_contents($dir . '/data/GeoIPv4.dat', $newfilev4);
// unlink($dir . '/data/OLD_GeoIPv4.dat');
}
if ( file_exists( $localfilev6 ) ) {
rename($dir . '/data/GeoIPv6.dat', $dir . '/data/OLD_GeoIPv6.dat');
$newfilev6 = file_get_contents('http://gdriv.es/geoipupdate/GeoIPv6.dat');
file_put_contents($dir . '/data/GeoIPv6.dat', $newfilev6);
// unlink($dir . '/data/OLD_GeoIPv6.dat');
}
}
Here's the output:

you must change the setting in the php.ini upload_max_filesize = 2M
and max_execution_time = X according to your need.

Edit php.ini to allow bigger upload first. Add (or find & edit) upload_max_filesize = 2M to your php.ini.
If that doesn't work, consider file_get_contents (= downloading) failing in the first place.
Your connection could be timing out before it can fetch the whole data. Try this.
(Sorry I can't comment everywhere yet that I had to answer on guessing)
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 120
)
)
);
file_get_contents("http://gdriv.es/geoipupdate/GeoIPv4.dat", 0, $ctx);

Hosting the files on a different server fixed it.

Related

How can a create a folder and save a image on my server in php?

Below I have left my code. It currently works in my development environment (localhost), but when I push the changes to my live server it seems like my php doesn't create the folder/file.
public static function saveImage($image, $name, $path = '')
{
$img_data = explode(',', $image);
$mime = explode(';', $img_data[0]);
$data = $img_data[1];
$extension = explode('/', $mime[0])[1];
if(!file_exists('../public/media/img/' . $path)){
mkdir('../public/media/img/' . $path, 0755);
echo('Test1');
}
echo('test2');
file_put_contents('../public/media/img/' . $path . $name . '.' . $extension, base64_decode($data));
return 'media/img/' . $path . $name . '.' . $extension;
}
Locally it will hit echo('test1') the first time, then it will only hit echo('test2'). When its on the server it always hits the echo('test1')
By default mkdir is not create a path recursively. An example if on your server you dont have a ../public/media folder, mkdir returns false and dont create a path.
To solve this pass a third parameter to mkdir as true:
mkdir('../public/media/img/' . $path, 0755, true);
Do yourself a favour and use absolute pathes...
You can use the constant __DIR__ to evaluate the folder in which the script actually resides.
Relative pathes are calculated from the current working directory, which can be different than __DIR__

Warning: move_uploaded_file(): it is moved but the Filesize stays at zero

I have been using an upload script on my server, like below
$newname = time() . '_' . $_FILES[$file]["name"];
if (strtolower(end(explode('.', $_FILES[$file]["name"]))) != 'pdf' AND $file != "damage_attachment_damageform_1" AND $file != "damage_attachment_damageform_2" AND $file != "damage_attachment_damageform_3" AND $file != "damage_attachment_damageform_4") {
if (move_uploaded_file($_FILES[$file]["tmp_name"], $_SERVER['DOCUMENT_ROOT'] . '/components/com_fleet/uploads/docs/' . $newname)) {
$images[] = $_SERVER['DOCUMENT_ROOT'] . '/components/com_fleet/uploads/docs/' . $newname;
$docs[] = $_SERVER['DOCUMENT_ROOT'] . '/components/com_fleet/uploads/docs/' . $newname;
} else {
die();
}
}
It uploads an image fine, but since a few days a get a Warning: move_uploaded_file(): Unable to move error. Ive seen these a dozen of times while learning to program, so I did all the usual stuff, check paths, the $_FILES[$file]["error"] and check all the right CHMODs. All is fine, path is spot-on, chmod is too, no errors etc...
1 extra weird thing I noticed the file does get written to the right /docs map but its Filesize is empty, and move_upload_file still sends false...
What am I forgetting? CHOWN maybe? And how can I solve that, I dont have SSH access or something.
Graa after an hour I now found out what was wrong, server Disk Quota was exceeded. Maybe people can still benefit from my problems...

How do I set relative paths in PHP?

I have an absolute path of (verified working)
$target_path = "F:/xampplite/htdocs/host_name/p/$email.$ext";
for use in
move_uploaded_file($_FILES['ufile']['tmp_name'], $target_path
However when I move to a production server I need a relative path:
If /archemarks is at the root directory of your server, then this is the correct path. However, it is often better to do something like this:
$new_path = dirname(__FILE__) . "/../images/" . $new_image_name;
This takes the directory in which the current file is running, and saves the image into a directory called images that is at the same level as it.
In the above case, the currently running file might be:
/var/www/archemarks/include/upload.php
The image directory is:
/var/www/archemarks/images
For example, if /images was two directory levels higher than the current file is running in, use
$new_path = dirname(__FILE__) . "/../../images/" . $new_image_name;
$target_path = __DIR__ . "/archemarks/p/$email.$ext";
$target_path = "archemarks/p/$email.$ext";
notice the first "/"
/ => absolute, like /home
no "/" => relative to current folder
That is an absolute path. Relative paths do not begin with a /.
If this is the correct path for you on the production server, then PHP may be running in a chroot. This is a server configuration issue.
Assuming the /archemarks directory is directly below document root - and your example suggests that it is -, you could make the code independent of a specific OS or environment. Try using
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/archemarks/p/$email.$ext";
as a generic path to your target location. Should work fine. This notation is also independent of the location of your script, or the current working directory.
Below is code for a php file uploader I wrote with a relative path.
Hope it helps. In this case, the upload folder is in the same dir as my php file. you can go up a few levels and into a different dir using ../
<?php
if(function_exists("date_default_timezone_set") and function_exists("date_default_timezone_get"))
#date_default_timezone_set('America/Anchorage');
ob_start();
session_start();
// Where the file is going to be placed
$target_path = "uploads/" . date("Y/m/d") . "/" . session_id() . "/";
if(!file_exists( $target_path )){
if (!mkdir($target_path, 0755, true))
die("FAIL: Failed to create folders for upload.");
}
$maxFileSize = 1048576*3.5; /* in bytes */
/* Add the original filename to our target path.
Result is "uploads/filename.extension" */
$index = 0;
$successFiles = array();
$failFiles = null;
$forceSend = false;
if($_SESSION["security_code"]!==$_POST["captcha"]){
echo "captcha check failed, go back and try again";
return;
}
foreach($_FILES['attached']['name'] as $k => $name) {
if($name != null && !empty($name)){
if($_FILES['attached']['size'][$index] < $maxFileSize ) {
$tmp_target_path = $target_path . basename( $name );
if(move_uploaded_file($_FILES['attached']['tmp_name'][$index], $tmp_target_path)) {
$successFiles[] = array("file" => $tmp_target_path);
} else{
if($failFiles == null){
$failFiles = array();
}
$failFiles[] = array ("file" => basename( $name ), "reason" => "unable to copy the file on the server");
}
} else {
if($failFiles == null){
$failFiles = array();
}
$failFiles[] = array ("file" => basename( $name ), "reason" => "file size was greater than 3.5 MB");
}
$index++;
}
}
?>
<?php
$response = "OK";
if($failFiles != null){
$response = "FAIL:" . "File upload failed for <br/>";
foreach($failFiles as $k => $val) {
$response .= "<b>" . $val['file'] . "</b> because " . $val['reason'] . "<br/>";
}
}
?>
<script language="javascript" type="text/javascript">
window.top.window.uploadComplete("<?php echo $response; ?>");
</script>

PHP Editing of Files Via FTP

Below is a script I am using to modify some files with placeholder strings. The .htaccess file sometimes gets truncated. It's about 2,712 bytes in size before editing and will vary in size after editing depending on the length of the domain name. When it gets truncated, it ends up around 1,400 bytes in size.
$d_parts = explode('.', $vals['domain']);
$ftpstring = 'ftp://' . $vals['username']
. ':' . $vals['password']
. '#' . $vals['ftp_server']
. '/' . $vals['web_path']
;
$stream_context = stream_context_create(array('ftp' => array('overwrite' => true)));
$htaccess = file_get_contents($ftpstring . '.htaccess');
$htaccess = str_replace(array('{SUB}', '{DOMAIN}', '{TLD}'), $d_parts, $htaccess);
file_put_contents($ftpstring . '.htaccess', $htaccess, 0, $stream_context);
$constants = file_get_contents($ftpstring . 'constants.php');
$constants = str_replace('{CUST_ID}', $vals['cust_id'], $constants);
file_put_contents($ftpstring . 'constants.php', $constants, 0, $stream_context);
Is there a bug in file_get_contents(), str_replace(), or file_put_contents()? I have done quite a bit of searching and haven't found any reports of this happening for others.
Is there a better method of accomplishing this?
SOLUTION
Based on Wrikken's response, I started using file pointers with ftp_f(get|put), but ended up with zero length files being written back. I stopped using file pointers and switched to ftp_(get|put), and now everything seems to be working:
$search = array('{SUB}', '{DOMAIN}', '{TLD}', '{CUST_ID}');
$replace = explode('.', $vals['site_domain']);
$replace[] = $vals['cust_id'];
$tmpfname = tempnam(sys_get_temp_dir(), 'config');
foreach (array('.htaccess', 'constants.php') as $file_name) {
$remote_file = $dest_path . $file_name;
if (!#ftp_get($conn_id, $tmpfname, $remote_file, FTP_ASCII, 0)) {
echo $php_errormsg;
} else {
$contents = file_get_contents($tmpfname);
$contents = str_replace($search, $replace, $contents);
file_put_contents($tmpfname, $contents);
if (!#ftp_fput($conn_id, $remote_file, $tmpfname, FTP_ASCII, 0)) {
echo $php_errormsg;
}
}
}
unlink($tmpfname);
With either passive of active ftp, I've never had much luck file using the file-family of functions with the ftp wrappers, usually with that kind of truncation problem. I usually just revert to the ftp functions with passive transfers, which do make it harder to switch, but work flawlessly for me.

PHP copy says file does not exist when it does

im using the following code;
if( ! file_exists( $path ) ) { die( "'" . $path . "' not vaild path"); }
copy( $path, ltrim($create_folder . ltrim($path, "./"), ".") );
echo "'" . $path. "' => '" . $create_folder . ltrim($path, "./") . "'<br />";
The first if statement returns true yet the copy function returns;
Warning: copy('./files/c7a628cba22e28eb17b5f5c6ae2a266a/0003.css') [function.copy]: failed to open stream: No such file or directory
'./files/c7a628cba22e28eb17b5f5c6ae2a266a/0003.css' => './224efcdebda48350056af291f64a9311/files/8b571e7fbf9bacf4473024b11f78bc0dfiles/c7a628cba22e28eb17b5f5c6ae2a266a/0003.css'
If anyone knows why it would be much appreciated.
You might notice that your second half is missing a slash. As in, one of your path elements is "8b571e7fbf9bacf4473024b11f78bc0dfiles" instead of "8b571e7fbf9bacf4473024b11f78bc0d/files". Try $create_folder . '/' . ltrim($path, "./")
But the real answer is "your file actually does not exist. No, really, PHP is correct". It's just talking about the destination not existing; the source is fine.

Categories