PHP fopen() on local file that DOES exist - php

Using php 5.2.17, on a Linux Server. My office production machine is Windows7 Professional with Service Pack 1 installed.
Trying desperately -- and so far, in vain -- to get fopen() to find and open a .csv file on my local machine in order to import records to an existing MySQL database on the server. Consistently getting a "failed to open stream" error message.
Here is part of the code, with explanatory notes / server responses, including notes on what I have tried:
ini_set('track_errors', 1); // Set just to make sure I was seeing all of the rrror codes
ini_set ('user_agent', $_SERVER['HTTP_USER_AGENT']); // Tried after reading a note; no effect
error_reporting(E_ALL); // Again, just to make sure all error codes visible!
echo(get_include_path()."<br />"); // Initially returns: .:/usr/local/php5/lib/php
set_include_path("C:\SWSRE\\"); // Have tried with BOTH forward and backslashes, BOTH single and doubled, in every conceivable combination!
ini_set('safe_mode_include_dir',"C:\SWSRE"); // Ditto here for slashes!
echo(get_include_path()."<br />"); //NOW echoes "C:\SWSRE\"
clearstatcache(); // Just in case this was a problem -- added after reading note # php.net
$file = "Individuals.txt"; // This absolutely DOES exist locally in C:\SWSRE\ (29Mb)
// Inserted following tests to see if it even SEES the file. It does NOT.
if (file_exists("Individuals.txt")) {
echo("File EXISTS!!!<br />");
} else {
echo("File does NOT exist!<br />"); // Echoes "File does NOT exist!"
}
if(is_readable($file)) {
echo 'readable' ;
} else {
echo 'NOT readable!<br />'; // Echoes "NOT readable!"
}
if(is_writable($file)) {
echo 'writable ' ;
} else {
echo 'NOT writable!<br />'; // Echoes "NOT readable!"
}
$handle = fopen("Individuals.txt", "r+", TRUE);
Here are the final PHP error messages:
Warning: fopen(Individuals.txt) [function.fopen]: failed to open stream: No such file or directory in /home/content/b/u/r/burtsweeto/html/ADREImport.php on line 145
array(4) { ["type"]=> int(2) ["message"]=> string(118) "fopen(Individuals.txt) [function.fopen]: failed to open stream: No such file or directory" ["file"]=> string(56) "/home/content/b/u/r/burtsweeto/html/ADREImport.php" ["line"]=> int(145) }
Finally, I have tried putting the file up in the directory where the PHP script is running; and it does work exactly correctly there! I'm just trying to minimize ongoing headaches for the end-user by not having to upload a huge file before doing the import.
Any suggestions that I have not tried?

Add the full path to $file, like this:
$file = "C:\\SWSRE\\Individuals.txt";
set_include_path() and the ini_set() do what they sound like; they adjust include paths, which is not the same as all paths. file_exists() expects either an absolute path or a path relative to the PHP file calling it. It is not affected by set_include_path() or ini_set('safe_mode_include_dir',...)

Related

PHP flock not having any effect in ubuntu

I have one php process locking a file with flock.
I then start another process that deletes the file.
On windows, I get the correct behaviour where the locked file is not able to be deleted, however on ubuntu (both wsl and a full Ubuntu installation) I am always able to delete the file.
I have read other similar questions but they all seem to tested wrong.
I am pretty sure I am testing this correctly.
UPDATED: More thorough testing.
After reading Why is unlink successful on an open file? and the delete Queue in the file system I needed to also test read and write.
Testing method.
Open a terminal and run my test file:
php test/flock_file_locking_with_splfileobject.php 👈 locks the file and waits for 30 seconds
Open a second terminal and run the following:
php test/flock_file_locking_with_splfileobject.php read
php test/flock_file_locking_with_splfileobject.php write
php test/flock_file_locking_with_splfileobject.php delete
Here's the contents of test/flock_file_locking_with_splfileobject.php
See comments in the code describing the output I get.
<?php
$me = array_shift($argv);
$command = array_shift($argv);
$fileName = 'cats';
switch ($command) {
case 'delete':
//attempt to delete the file
if (!unlink($fileName)) {
echo "Failed to delete file!";
exit(1);
}
echo "File was deleted:";
var_dump(file_exists($fileName) === false);
//on linux I get File was deleted:bool(true)
//on windows I get 'PHP Warning: unlink(cats): Resource temporarily unavailable'
break;
case 'write':
$written = file_put_contents($fileName, 'some datah!');
echo "Written bytes:";
var_dump($written);
//on Linux I get 'Read: string(21) "file should be locked"'
// OR 'Read: string(11) "some datah!"' if I run the write command first.
//on windows i get Warning: file_put_contents(): Only 0 of 11 bytes written, possibly out of free disk space
break;
case 'read':
$read = file_get_contents($fileName);
echo "Read: ";
var_dump($read);
// on Linux i get 'Written bytes:int(11)'
// on windows I get no error but I get no data 'Read: string(0) ""'
break;
default:
$file = new \SplFileObject($fileName, 'a+');//file gets created by a+
if (! $file->flock(LOCK_EX)) {
echo "Unable to lock the file.\n";
exit(1);
}
$file->fwrite('file should be locked');
echo "File should now be locked, try running the delete/write/read commands in another terminal.",
"I'll wait 30 seconds and try to write to the file...\n";
sleep(30);
if (! $file->fwrite('file is now unlocked')) {
echo "Unable to write to file.\n";
exit(1);
}
//in either system this file write succeeds regardless of whats going on.
break;
}
echo "\n";
Windows behaves as it should but on Linux,
my 2nd process can do anything it likes to the file while the first process apparently gets a successful file lock.
Obviously, can't trust flock on production if it only works on windows.
Is there any way to actually get an exclusive file lock?
Any ideas?

Cannot use absolute path to a file received via STDIN in PHP CLI

As a part of some automation scripts I'm writing a function that asks the user for an absolute path to the file she wishes to use. The problem is that PHP throws Warning: fopen("/path/to/desired/file/file.txt"): failed to open stream: No such file or directory in /path/to/my/script/script.php on line 13 when the user inserts the file. Here is the general function:
function askFile() {
echo "Please specify the full path to your file.\n";
$usrInput = trim(fgets(STDIN, 1024));
$usrInput = '"' . $usrInput . '"';
echo $usrInput . "\n"; // Just to test the final string.
echo is_string($usrInput) ? "It's a string.\n" : "It's not a string.\n"; // Just to confirm that the variable holds a string.
if($handle = fopen($usrInput, 'r')) {
echo "Thank you. The file is now opened.\n";
} else {
"Sorry, could not open the file for reading.\n";
}
}
askFile();
The permissions for the file are, for testing purposes, wide open at 777. When I simply hard code the absolute path right inside fopen() everything works as expected, therefore the problem only occurs when the input comes from STDIN.

Cannot open file using fopen (php)

I am trying to open a file for reading in php script but having trouble.
This is my code
$fileHandle = fopen("1234_main.csv", "r")or die("Unable to open");
if (!file_exists($fileHandle))
{
echo "Cannot find file.";
}
The script is in the same directory as the file I am trying to read and there are no other read/write permission errors as I can create/read other files in the same directory.
When I run the script I just get the "Cannot find file" error message. Why is this error message being shown? Surely if fopen() can't open the file the "or die statement" should end the script?
Also, why can't I open the file when it definitely exists and is in the same location as the script (I have also tried using the full path of the filename instead of just the filename).
I am fairly new to php (but have exp in c++) so if its a stupid question I apologize.
Many thanks
In PHP, file_exists() expects a file name rather than a handle. Try this:
$fileName = "1234_main.csv";
if (!file_exists($fileName))
{
echo "Cannot find file.";
} else {
$fileHandle = fopen($fileName, "r")or die("Unable to open");
}
Also keep in mind that filenames have to be specified relative to the originally requested php-script when executing scripts on a web server.
You can use file_get_content() for this operation. On failure, file_get_contents() will return FALSE.For example
$file = file_get_contents('1234_main.csv');
if( $file === false ){
echo "Cannot find file.";
}
file_exists() take the file-name as input, but the logic of your code has problem. You first try to open a file then you check its existence?
You first should check its existence by file_exists("1234_main.csv") and if it exists try to open it.
file_exists takes a string, not a file handle. See http://php.net/manual/en/function.file-exists.php

In PHP, check if a file can be deleted

I have a large video file that is streamed using a streaming server outside my control, and sometimes I want to delete the video file. When the file happens to be viewed by someone using the streaming server, PHP errors with "Permission denied".
I would like to check before attempting to delete if the file can be deleted or not. I do not want to actually try to delete the file and see if that fails, I would like to check beforehand.
This is my code so far:
$file = "video.flv";
$file2 = "newvideoname.flv";
clearstatcache();
if (is_writeable($file)) {
echo "is writeable";
}
else {
echo "is NOT writeable";
}
echo "\n";
$fh = fopen($file, 'a+');
if (!flock($fh, LOCK_EX | LOCK_NB)) {
// file locked, do something else
echo "is locked";
}
else {
echo "not locked!";
}
fclose($fh);
echo "\n";
if (touch($file)) {
echo "modification time has been changed to present time";
}
else {
echo "Sorry, could not change modification time";
}
echo "\n";
rename($file, $file2);
The output I get when I stream video.flv while executing the code:
is writeable
not locked!
modification time has been changed to present time
PHP Warning: rename(video.flv,newvideoname.flv): Permission denied in ...
Sometimes I get:
is writeable
PHP Warning: fopen(video.flv): failed to open stream: Permission denied ...
PHP Warning: flock() expects parameter 1 to be resource, boolean given
is locked
PHP Warning: fclose(): supplied argument is not a valid stream resource
PHP Warning: touch(): Utime failed: Permission denied
Sorry, could not change modification time
PHP Warning: rename(video.flv,newvideoname.flv): Permission denied ...
So sometimes the file cannot be locked by PHP and it cannot be touch()ed by PHP, and then of course the rename doesn't work, but sometimes PHP says "all is fine" until the rename command. The rename command has never worked by random chance.
What should I do with the file?
if (!flock(fopen($file, 'a+'), LOCK_EX | LOCK_NB)) {
You are locking the file. Make sure you unlock it again if the call succeeds (just after echo "not locked!";
The problem as I see it is that when you checked if the file is locked with flock you opened a resource to the file but did not close the file. So the file is now locked and you can't rename it.
You cannot delete a file that is streaming...if you REALLY WANT TO...make a copy, raname it, and put the file(original) in a stack(DB) and have a cron job or something to delete it...
The solution is here :
$file = "test.pdf";
if (!is_file($file)) {
print "File doesn't exist.";
} else {
$fh = #fopen($file, "r+");
if ($fh) {
print "File is not opened and seems able to be deleted.";
fclose($fh);
} else {
print "File seems to be opened somewhere and can't be deleted.";
}
}

open_basedir won't let me write file, but directory seems correct?

Short story:
I'm getting an open_basedir restriction in my php script - a simple "test writing a new file to disk" script. It SEEMS to me that I've got the open_basedir settings correct and the file is in the right location - but no luck, just the same error every time. I've searched for similar open_basedir problems on this site, but I've not seen any with this problem - where the directory looks right but it still throws errors.
My guesses as to what the problem is:
1) open_basedir doesn't work the way I think it does
2) My settings are wrong and I'm just not seeing it
3) It's actually something else, like IIS read/write permissions, etc
4) ???
Long story:
I'm working on an IIS server with PHP and I'm trying to get the following code snippet to work (a simple write file test):
date_default_timezone_set('America/Chicago');
$myFile = 'testfile.txt';
$fh = fopen($myFile, 'w') or die("can't open file");
$stringData = "Some Text\n";
fwrite($fh, $stringData);
$stringData = "Some More Text\n";
fwrite($fh, $stringData);
fclose($fh);
This php script is located at C:\inetpub\wwwroot\WEBDIRECTORY\test_write.php on my server
Here is my php.ini setting for open_basedir:
open_basedir = c:\inetpub\wwwroot;c:\inetpub\wwwroot\WEBDIRECTORY
Whenever I open the script's page, I am expecting to see no output, and then there should be a new file written on the server when I check back. This is what I get instead:
Warning: fopen(): open_basedir
restriction in effect.
File(testfile.txt) is not within the
allowed path(s): (c:\inetpub\wwwroot)
in
C:\inetpub\wwwroot\WEBDIRECTORY\test_write.php
on line 5 Warning:
fopen(testfile.txt): failed to open
stream: Operation not permitted in
C:\inetpub\wwwroot\WEBDIRECTORY\test_write.php
on line 5 can't open file
I've tried a lot of permutations: originally the open_basedir line was just
open_basedir = c:\inetpub\wwwroot
...but that didn't work, either.
I've also tried entering an absolute path for testfile.txt (c:\inetpub\wwwroot\WEBDIRECTORY\testfile.txt, etc) instead of just the name of the file itself, and I keep getting the same error message.
Any ideas? Thanks so much for your help.
Okay, so sorry to waste everyone's time - turns out it was a server setting my system administrator had set for me. (I'm new to this so I'll explain in general terms that I understand)
He'd set it up so that the server would not resolve an address for any files in the web directory except certain types you expect to find on a website, such as .htm, .html, .php, .jpg, etc. The file I was trying to read was .txt.
So, I wrote some test code:
$test = realpath('c:\inetpub\wwwroot\WEBDIRECTORY\testfile.php');
echo ("test = $test\n");
if($test == FALSE){
echo ("... is FALSE\n");
}
$test = realpath('c:\inetpub\wwwroot\WEBDIRECTORY\testfile.txt');
echo ("test = $test\n");
if($test == FALSE){
echo ("... is FALSE\n");
}
Which promptly returned this:
test = C:\inetpub\wwwroot\WEBDIRECTORY\testfile.php
test = ... is FALSE
So, realpath is refusing to return an address for anything ending in .txt, but is more than happy to do that for a .php file. This means that WHENEVER I put in an otherwise legal (within the basedir) filename that ends in an illegal extension, the server resolves that address not as "C:\inetpub\wwwroot\WEBDIRECTORY\testfile.txt" but as "". And of course, an empty string is not going to be in the basedir, returning open_basedir restriction errors.
BIZARRE! But makes sense now that I finally traced it back to its source. Thanks for all the tips! It helped me go through process of elimination and figure this one out.
It appears to be a permissions problem. Check the permissions on C:\inetpub\wwwroot\WEBDIRECTORY\ If special permissions are required sometimes you have to change the permissions on the .PHP script doing the writing. Typically you need both the directory and the script set, not just one or the other.
Here is a good script from the PHP manual for opening a file for writing:
$filename = 'test.txt';
$somecontent = "Add this to the file\n";
// Let's make sure the file exists and is writable first.
if (is_writable($filename)) {
// In our example we're opening $filename in append mode.
// The file pointer is at the bottom of the file hence
// that's where $somecontent will go when we fwrite() it.
if (!$handle = fopen($filename, 'a')) {
echo "Cannot open file ($filename)";
exit;
}
// Write $somecontent to our opened file.
if (fwrite($handle, $somecontent) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
echo "Success, wrote ($somecontent) to file ($filename)";
fclose($handle);
} else {
echo "The file $filename is not writable";
}

Categories