PHP: ftp_get() can download file with same name only once - php

I'm having a strange problem using ftp_get() on one of the two identical instances. One is on localhost and another on an actual server. I'm using the following to download a file via FTP. Both of the instances download from the same FTP servers with the same credentials and same paths.
$result = ftp_get($connection, $downloadPath, $serverPath, FTP_BINARY);
if ($result) {
$successfulWrites[] = $downloadPath; // file name only without path
} else {
// on second attempt to download file with same name, ftp_get() returns false
// this is where I throw an exception in my code
}
On my localhost, I can download the same file over and over, and it doesn't matter what the file name on the FTP server is or where it's located.
On second instance, which is identical to the localhost's (i.e. pulled from the same git repo) in terms of code, I can download a file once, but the same file cannot be downloaded again, and ftp_get() returns false. If I change the name of the file on the FTP server, I can download it, but after that it won't work again. i.e. ftp_get() will return false.
I don't have access to the FTP server log. If it's available, I'm going to try to get it today from the host. But can anyone think of a reason this might be happening? ftp_get() just returns true or false without any explanation, so I'm pretty stuck with this.
I'm using PHP 5.4, and I have no idea what the spec is of the FTP (regular FTP) server.

As discussed, it sounded like ftp_get was successfully obtaining the file and writing it locally. I wonder whether due to a permissions problem, when it tries to write the file locally again, it fails. Thus, the FTP channel itself is fine, and the problem is just local.
I'm somewhat surprised at this though, as I would imagine PHP would have raised a warning. Is your error_reporting set to allow this whilst you are debugging?

Related

PHP connection to remote mysql with ssl works via command but not in browser

I want to connect to a remote (AWS) mysql server using ssl in PHP.
My script works when I execute it via command line, but doesn't when I call it from the browser.
$con=mysqli_init();
mysqli_ssl_set($con,NULL,NULL,"path/to/cacert.pem",NULL,NULL);
$link = mysqli_real_connect($con, "host", "username", "password");
I am using php7/Apache/CentOs. I tried changing the ownership and permissions of the CA file, and noticed that it requires read permission the be executed on console. But in browser even if I give full permission to everybody (chmod 777) it still doesn't work.
The error i get is:
Warning: failed loading cafile stream.
When I check existence of file it returns true, but when I check is_readible, then also error.
Can somebody help?Thanks!
So as I figured there was (is) something wrong with readability and maybe permissions. I could narrow down the problem to the certificate file being existent but not readable. I moved it to my server with filezilla via ftp.
I could solve my problem by creating a new .pem file and simply copying the content of my original file into it. This one is readable now and works in browser, but I can't figure out why as they both have the same chmod xxx permissions and chown ownership.
Detailed description(for users with similar problem using AWS MYSQL):
open rds-combined-ca-bundle.pem file(download link: https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem) in text editor.
Copy content.
On your server, where php script should run create new file and paste text into it.(it might require some additional editing, begin/end tags in separate line and new lines end at the same place as in original text)

Check PDF number pages with PHP (in Linux)

I have a webpage where I let users to upload files to the account folder. Exactly PDF and JPG files only. I want to count the number of pages inside each PDF uploaded to show it to the users.
To do this, I was using PDFINFO linux library, part of XPDF proyect.
This is the man page of the binary file: http://linuxcommand.org/man_pages/pdfinfo1.html
You can download the .zip with the binaries there: http://www.foolabs.com/xpdf/download.html
My code (this worked perfectly, but yesterday it failed):
function getNumPagesInPDF($document){
if(!file_exists($document))return null;
$cmd = "pdfinfo";
// Open the document
exec($cmd." '".$document."'", $output);
// Browse the data
$pagecount = 0;
foreach($output as $op){
// Extrac number of pages
if(preg_match("/Pages:\s*(\d+)/i", $op, $matches) === 1){
$pagecount = intval($matches[1]);
break;
}
}
return $pagecount;
}
I can run the command in SSH, and it works in the server. Now, this code doesn't work in PHP, but nothing changed the code.
AH! a little addition: I checked exec works in my PHP using:
function exec_enabled() {
$disabled = explode(',', ini_get('disable_functions'));
return !in_array('exec', $disabled);
}
if (exec_enabled()){
echo "exec funciona";
}
Another addition: PHP didn't shows any error related with that and I have the error logging enabled to a log file (including warnings). My host recently activated mod_security.
TASK1: Try $document variable: the path is ok, relative to the place where the php code file is placed. The path exists and the file too.
TASK2: Check if $output variable has anything: NO, $output array is empty! Why? cannot understand.
TASK3: Check the $cmd." '".$document."'" : it's ok, and copied the "result" to ssh works. I'm lost.
As per the comment discussion, we've seen that running a binary using a bare filename does not always work. This is as true on the console as it is inside a system command like exec().
When you run pdfinfo in either environment, the system will search through the environment variable PATH to discover which directories to find it in. This variable is nearly always different between your user account and the Apache environment, which is why it is important to always specify the fully-qualified filename when running a binary programmatically.
As far as I know, exec() does not regard the folder containing the current PHP script as the current working directory. Even if it did, the current directory . would need to be in the Apache user's PATH in order for this to be found. Thus, I am not sure why this used to work for you, but it emphasises the importance of the above lesson: always use the full path.
You should also read the path from a settings file, rather than hardwiring it in code. This will help you as you move from local, test, staging and live environments of your app, which may store this binary in different locations.

PHP Read/Write files on remote server

I'm making a utility that provides a GUI to easy edit certain values in a csv file on a remote server. My boss wants the utility in php running on the private webserver. I'm new to php, but I was able to get the GUI file modifier working locally without issues. The final piece now is rather than the local test file I need to grab a copy of the requested file off of the remote server, edit it, and then replace the old file with the edited one. My issue is uploading and downloading the file.
When I searched for a solution I found the following:
(note in each of these I am just trying to move a test file)
$source = "http://<IP REMOTE SERVER>/index.html";
$dest = $_SERVER['DOCUMENT_ROOT']."index.html";
copy($source, $dest);
This solution ran into a permissions error.
$source ="http://<IP REMOTE SERVER>/index.html";
$destination = $_SERVER['DOCUMENT_ROOT']."newfile.html";
$data = file_get_contents($source);
$handle = fopen($destination, "w");
fwrite($handle, $data);
fclose($handle);
This also had a permissions error
$connection = ssh2_connect('<IP REMOTE SERVER>', 22);
ssh2_auth_password($connection, 'cahenk', '<PASSWORD>');
ssh2_scp_recv($connection, '/tmp/CHenk/CHenk.csv', 'Desktop/CHenk.csv');
This solution has the error Fatal error: Call to undefined function ssh2_connect() which I have learned is because the function is not a part of the default php installation.
In closing, is there any easy way to read/write files to the remote server through php either by changing permissions, having the php extension installed, or a different way entirely that will work. Basically I'm trying to find the solution that requires the least settings changes to the server because I am not the administrator and would have to go through a round about process of getting any changes done. If something does need to be changed instructions on doing so or a link to instructions would be greatly appreciated.
Did you set the enable-url-fopen-wrapper in your php.ini?(only if your php version is older)
Please look # php remote files storing in example 2

PHP curl fails to download data when outputting to a file but ok when printing to stdout

This has been bugging me for literally hours already.
I can't seem to figure out why PHP cURL won't download data to a file. (CURLOPT_FILE is set to a local file.) I am not getting any data. I periodically check the file size of the destination file and it is always zero. To give you a background, I am downloading a 90kb jpeg file (for testing purposes).
This is working on my local computer (XP) but not in the website I am working on (Windows Server 2003).
I did several tests which made the scenario even weirder.
I disabled CURLOPT_FILE to print the data returned by curl into standard output, and the binary data printed.
Having experienced blocked websites before (since the server implements access control), I tried accessing the file from internet explorer and i was able to see it.
Having experienced blocked downloads before, I tried downloading the file from internet explorer and it was downloaded.
The file is created by fopen('', 'w') but the size remains 0. Despite this successful file creation, I thought maybe PHP has a problem with filesystem write privileges, I set the exe to be run even by non-admin users. Still no download.
Has this ever occured to anybody?
Any pointers will be appreciated. I am really stuck.
Thank you.
Here's the curl options I set:
$connection = curl_init($src);
// If these are not set, curl_exec outputs data.
// If these are set, curl_exec does not send any data to the file
// pointed to by $file_handler. $file_handler is not null
// because it is opened as write (non-existing file is created)
curl_setopt($connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt( $connection, CURLOPT_FILE, $file_handler );
PS: I'm doing these tests using the command line and not the browser.
you might not have permissions to write to the file.
I don't think you have to set CURLOPT_RETURNTRANSFER and if you are running from the command line be sure to run the php with admin rights. Not sure how it works in windows but in linux I always sudo every command line script I run.
Also if php safe mode is on be sure to also give the the directory the same (UID) owner as the php file. Hmh but since you can create the file (with 0 filesize) it might have nothing to do with rights... could you check the *open_basedir* php setting on your server? If it is set cUrl is not allowed to use file protocol... did you check the log files from your server? maybe there is an error.
You may need to figure out what user runs your php, if the user running the php script (the one that calls php ) is not authorized to write to the directory of the file, or to the /path/to/file , you may need to adjust your file permissions.

move_uploaded_file hangs?

I seem to have a bizarre error I just can't quite figure out. My website was working on one server, but when I transferred it to a new one it stopped working. I believe I've narrowed the error down to this line of code:
$ret = move_uploaded_file($tmp_name, $orig_path);
This is executed through an AJAX call so it's a little bit tricky to debug, but the script can send back an error code and then my JavaScript will alert it. So, I've wrapped it in two of these debug statements:
echo json_encode(array(
'success' => false,
'errno' => $tmp_name.' -> '.$orig_path,
));
exit;
$ret = move_uploaded_file($tmp_name, $orig_path);
echo json_encode(array(
'success' => false,
'errno' => 'no error',
));
exit;
The first one works fine and spits out something like:
error /tmp/phpk3RICU -> /home/username/Websites/website/photos/o/2-4a3354dd017a9.jpg
Perhaps I'm a bit of a linux noob, but I can't actually find /tmp/phpk3RICU on my system (is it deleted as soon as the script exits or what?). More on that in a sec though.
If I delete the first debug check and let move_uploaded_file run, the 2nd debug check never seems to get executed, which leads me to believe move_uploaded_file is hanging.
If instead of using $tmp_name I use a file I know doesn't exist, then the 2nd check DOES get executed. So... it seems like it just doesn't want to move that tmp file, but it's not reporting an error.
I'm running a fresh install of the LAMP stack on my Unbutu machine, installed through apt-get... let me know if you need more info.
Oh.. and don't know if it's relevant, but the file gets uploaded through flash.
Do you upload the file via the AJAX call?
Uploaded files are deleted as soon as the script you uploaded them to finishes executing - that's why you can't find it in /tmp.
Try telling PHP to spit out all errors:
error_reporting(E_ALL);
It could be a configuration discrepancy that is breaking it on one of your servers. From the move_uploaded_file() manual page:
Note: move_uploaded_file() is both
safe mode and open_basedir aware.
However, restrictions are placed only
on the destination path as to allow
the moving of uploaded files in which
filename may conflict with such
restrictions. move_uploaded_file()
ensures the safety of this operation
by allowing only those files uploaded
through PHP to be moved.
Ugh. The problem was with permissions. 755 was enough on the other server, but not for this server it seems... not really sure why, I guess PHP is running under a different user? I'm not really sure how the whole permissions stuff works. What really boggles me is why mkdir and move_uploaded_file didn't fail and return false...

Categories