Why does "return fopen" fail? - php

I have a function:
function open($file){
return fopen($file, 'w');
}
This is then called by:
function write($file,$text){
$h = $this->open($file);
fwrite($h,$text);
}
This doesn't work. It returns that fwrite was given an invalid resource stream.
This:
function open($file){
$h = fopen($file, 'w');
return $h;
}
Works fine, but I can't figure out why assigning a variable first works and directly returning fopen() doesn't.

Does it have something to do with the fact that you're within an object? The following script works for me:
<?php
function open($file) {
return fopen($file, 'w');
}
function write($file, $text) {
$h = open($file);
fwrite($h, $text);
}
write("test.txt", "hello\n");
?>
I'm running PHP 5.2.8 on Mac OS X 10.5.7.

It's probably just because you are working in the scope of an object, so it cleans up the resource stream too early - since it passes a resource stream byref, if you have a variable set, its byref'ing the variable instead of trying to do it to the resource stream - so it'll work.

declare a
var $file
then
$this->file = fopen(...)
return $this->file;
this will works because the $file variable has still a reference.

Related

How to check if bash input is being redirect to PHP script?

I'm writing a PHP script and I would like to be able to optionally use a file as the script input. This way:
$ php script.php < file.txt
I'm, actually, able to do that using file_get_contents:
$data = file_get_contents('php://stdin');
However, if I don't pass a file to the input, the scripts hangs indefinetelly, waiting for an input.
I tried the following, but it didn't work:
$data = '';
$in = fopen('php://stdin', 'r');
do {
$bytes = fread($in, 4096);
// Maybe the input will be empty here?! But no, it's not :(
if (empty($bytes)) {
break;
}
$data .= $bytes;
} while (!feof($in));
The script waits for fread to return a value, but it never returns. I guess it waits for some input the same way file_get_contents does.
Another attempt was made by replacing the do { ... } while loop by a while { ... }, checking for the EOF before than trying to read the input. But that also didn't work.
Any ideas on how can I achieve that?
You can set STDIN to be non-blocking via the stream_set_blocking() function.
function stdin()
{
$stdin = '';
$fh = fopen('php://stdin', 'r');
stream_set_blocking($fh, false);
while (($line = fgets($fh)) !== false) {
$stdin .= $line;
}
return $stdin;
}
$stdin = stdin(); // returns the contents of STDIN or empty string if nothing is ready
Obviously, you can change the use of line-at-a-time fgets() to hunk-at-a-time fread() as per your needs.

Create dynamic text file with php function

So I need to create a dynamic text file based on the name of a variable in php (ex: dynamicName.txt). I then need to write other variables in the file.
$testVar = "test.txt";
function sendCalc(){
global $testVar;
$objCalcTxt = ("C:\\xampp\\htdocs\\test.new\\upload\\$testVar");
$fp = fopen($objCalcTxt, 'x');
fwrite($fp, "Test\n");
fclose($fp);
When I do the above, the file is created with no problem, and all the data is written successfully. However, this is not a dynamic file name.
$objName = "dynamicName";
$ext = ".txt"
$dynamicNameTxt = $objName.$ext;
function sendCalc(){
global $objName;
global $ext;
global $dynamicNameTxt;
$objCalcTxt = ("C:\\xampp\\htdocs\\test.new\\upload\\$dynamicNameTxt");
$fp = fopen($objCalcTxt, 'x');
fwrite($fp, "Test\n");
fclose($fp);
When I try to concatenate the variable that contains the dynamic file name ($objName), with the $ext var, it does not want to create the file.
I echoed the $dynamicName var and it returns dynamicName.txt, so why doesn't this work with fopen. Essentially it has to be a problem with the concatenation right? If so, can I either concatenate a different way, or use a different method to open/create the file?
All help/ideas are appreciated.
I do not really know what you're trying to achieve with the line
$objCalcTxt = ("C:\\xampp\\htdocs\\test.new\\upload\\$dynamicNameTxt");
if from what i understand it should just be a string:
$objCalcTxt = "C:\\xampp\\htdocs\\test.new\\upload\\".$dynamicNameTxt;
Also I'd suggest you provide the needed variables as arguments for the function insted of using globals
function sendCalc($objName, $ext, $dynamicNameTxt){
...
}
You are declaring the global variables inside your function. This could destroy their initial values.
Instead of using global variables in your function, rather pass the variables as arguments:
$objName = "dynamicName";
$ext = ".txt"
$dynamicNameTxt = $objName.$ext;
function sendCalc(objName, $ext, $dynamicNameTxt)
{
$objCalcTxt = ("C:\\xampp\\htdocs\\test.new\\upload\\$dynamicNameTxt");
$fp = fopen($objCalcTxt, 'x');
fwrite($fp, "Test\n");
fclose($fp);
}
Your other option is to specifically call the global variable:
global $objName;
global $ext;
global $dynamicNameTxt;
$objName = "dynamicName";
$ext = ".txt"
$dynamicNameTxt = $objName.$ext;
function sendCalc()
{
$objCalcTxt = ("C:\\xampp\\htdocs\\test.new\\upload\\".$GLOBAL['dynamicNameTxt']);
$fp = fopen($objCalcTxt, 'x');
fwrite($fp, "Test\n");
fclose($fp);
}

Uploaded file with white space makes is_resource() fails - php

I have a script checking if a file exists:
function fileExists($url) {
$fh = fopen($url, 'r');
if (is_resource($fh)) {
fclose($fh);
return true;
}
return false;
}
Everything went right until I tried to uploaded files whose name contains white space. Call $url the file's url, when I put it in the browser, it displays correctly the file, but is_resource($fh) always returns false. Someone could help ?
Before $fh = fopen($url, 'r'); add this:
$parts = pathinfo($url);
$url = $parts['dirname'].'/'.rawurlencode($parts['basename']);
Btw, there is a PHP bug...

Use of "is_numeric" to safely read file that only contains a zero ("0")?

In my file read function, if($theData = #fread($fh, filesize($myFile)) was returning false if the target failed contained nothing but a zero, so I added a check for integer (is_numeric). Is this safe?
function readfilecontents($myFile)
{
if($fh = #fopen($myFile, 'r'))
{
$theData = #fread($fh, filesize($myFile));
if($theData || is_numeric($theData))
{
if(#fclose($fh))
{
return $theData;
}
}
}
return false;
}
No, this is not safe - e.g. if you're reading an empty file, your function will return false instead of an empty string. But there is no need for a function like this as file_get_contents() does the exact same thing (just faster).

Define array of file locations, parse and replace. Where's my error?

I'm trying to define an array with a list of file urls, and then have each file parsed and if a predefined string is found, for that string to be replaced. For some reason what I have isn't working, I'm not sure what's incorrect:
<?php
$htF = array('/home/folder/file.extension', '/home/folder/file.extension', '/home/folder/file.extension', '/home/folder/file.extension', '/home/folder/file.extension');
function update() {
global $htF;
$handle = fopen($htF, "r");
if ($handle) {
$previous_line = $content = '';
while (!feof($handle)) {
$current_line = fgets($handle);
if(stripos($previous_line,'PREDEFINED SENTENCE') !== FALSE)
{
$output = shell_exec('URL.COM');
if(preg_match('#([0-9]{1,3}\.){3}[0-9]{1,3}#',$output,$matches))
{
$content .= 'PREDEFINED SENTENCE '.$matches[0]."\n";
}
}else{
$content .= $current_line;
}
$previous_line = $current_line;
}
fclose($handle);
$tempFile = tempnam('/tmp','allow_');
$fp = fopen($tempFile, 'w');
fwrite($fp, $content);
fclose($fp);
rename($tempFile,$htF);
chown($htF,'admin');
chmod($htF,'0644');
}
}
array_walk($htF, 'update');
?>
Any help would be massively appreciated!
Do you have permissions to open the file?
Do you have permissions to write to /tmp ?
Do you have permissions to write to the destination file or folder?
Do you have permissions to chown?
Have you checked your regex? Try something like http://regexpal.com/ to see if it's valid.
Try adding error messages or throw Exceptions for all of the fail conditions for these.
there's this line:
if(stripos($previous_line,'PREDEFINED SENTENCE') !== FALSE)
and I think you just want a != in there. Yes?
You're using $htF within the update function as global, which means you're trying to fopen() an array.
$fh = fopen($htF, 'r');
is going to get parsed as
$fh = fopen('Array', 'r');
and return false, unless you happen to have a file named 'Array'.
You've also not specified any parameters for your function, so array_walk cannot pass in the array element it's dealing with at the time.

Categories