php : convert ressource stream in file - php

I get a ressource stream when I use fopen on a filepath I get from my database :
<?php
$query = "SELECT filepath
FROM files
WHERE id=123";
$result = do_query($query);
/*do_query() is a personal simplification*/
$line = mysql_fetch_array($result);
$file = fopen($line['filepath'], 'r');
/*var_dump on file return "resource(51) of type (stream)"*/
?>
But I my project I need a $_FILE type... Can I convert a ressource stream in $_FILE type?

$_FILES is not a "type", it's merely an array which holds certain information about uploaded files. First of all, if you have some piece of code which is hardcoded to use $_FILES, you should probably change it to accept a generic argument instead. Meaning, instead of:
function foo() {
echo $_FILES['tmp_name']:
}
Rewrite that to:
function foo($path) {
echo $path;
}
You can then call that function and pass it any path from anywhere. In your case you'd pass it $line['filepath'] as is. You don't need to fopen it, because then you get a resource, when you currently just want a path.
If you need to "fake" the $_FILES array, you need to construct it manually:
$_FILES['foo']['name'] = '..';
$_FILES['foo']['type'] = '..';
$_FILES['foo']['size'] = '..';
$_FILES['foo']['tmp_name'] = $line['filepath'];
$_FILES['foo']['error'] = UPLOAD_ERR_OK;
But again, you'll probably want to alter whatever code is hardcoded to use $_FILES instead of this hackaround.

Related

I want store value in file and read it using php

here I have value stored in $value1 variable and I want to store it's value in valuebxb.txt, and again I want to read that value from valuebxb.txt and store it to another variable $value2, here is a code from which I was able to create required file, but not able to store the value.
$value1 = round($value1, 4);
if (!file_exists('valuebxb.txt')) {
touch('valuebxb.txt', strtotime('-1 days')); //file is created
$file = fopen("valuebxb.txt","w"); //opening the file
fwrite($file,$value1); //storing the value of variable in file
fclose($file); //closing the file
}
I would recommend using file_get_contents() and file_put_contents() instead. They are much easier to use for reading and writing to files.
In your case, to write to a file:
file_put_contents('/path/to/file', $theValue);
(this will also create the file if it doesn't already exist)
And to read the value from the file:
// Define the variable with a default value
$value = null;
// Read from the file if it exists
if (is_file('/path/to/file')) {
$value = file_get_contents('/path/to/file');
}
A shorter version of reading using ternary:
$value = is_file('/path/to/file') ? file_get_contents('/path/to/file') : null;

Hashing an image from a remote location in PHP

Using a PHP script, I want to compare two images. One of the images is located on my server, and one is located on an external website. I have tried to compare the hashes of the two images to each other. Unfortunately, this only works when the two images are saved on my server. How can I make this work?
<?php
$localimage = sha1_file('image.jpg');
$imagelink = file_get_contents('http://www.google.com/image.jpg');
$ext_image = sha1_file($imagelink);
if($localimage == $ext_image){
//Do something
}
?>
If you are using php 5.1+ (which I hope) you can just write :
<?php
$localimage = sha1_file('image.jpg');
$ext_image = sha1_file('http://www.google.com/image.jpg');
if($localimage == $ext_image){
//Do something
}
?>
As sha1_file will work on remote wrappers.
Quote from PHP doc at https://secure.php.net/manual/en/function.sha1-file.php
5.1.0 Changed the function to use the streams API. It means that you can use it with wrappers, like sha1_file('http://example.com/..')
You are not using the sha1_file() properly in the second call.
sha1_file() expects the parameter to be a filename and you are using a memory buffer. So you have 2 options.
First using your current code, save the file to a temp location and use sha1_file()
<?php
$localimage = sha1_file('image.jpg');
$imagelink = file_get_contents('http://www.google.com/image.jpg');
file_put_contents('temp.jpg', $imagelink);
$ext_image = sha1_file('temp.jpg');
if($localimage == $ext_image){
//Do something
}
?>
Or use sha1() instead of sha1_file() on the contents of $imagelink
<?php
$localimage = sha1_file('image.jpg');
$imagelink = file_get_contents('http://www.google.com/image.jpg');
$ext_image = sha1($imagelink);
if($localimage == $ext_image){
//Do something
}
?>
Well actually maybe 3 options, see #Flunch's answer!

php Update filename from directory

so the title is not full clear, my question , I'm using the code to rename the file from directory present in the server the problem is i have to use the HTML form and php to update the file name, i want to do this : there will be an option on every file for renaming it when i click on the option the box pops up and i have to type the new name for file and save it , any help will be appreciated. (before down voting think about the question.)
The code that I'm using to update the file name
<?php
include("configuration.php");
$target = $_POST['filename'];
$newName = $_POST['newfilename'];
$actfoler = $_REQUEST['folder'];
$file = "files/users/";
$new ="files/users/";
$renameResult = rename($file, $new);
// Evaluate the value returned from the function if needed
if ($renameResult == true) {
echo $file . " is now named " . $new;
} else {
echo "Could not rename that file";
}
header("Location:".$_SERVER["HTTP_REFERER"]);
?>
Try changing these lines:
$file = "uploads/$loggedInUser->username$actfolder/$target";
$new ="uploads/$loggedInUser->username$actfolder/$newName";
To:
$file = "uploads/{$loggedInUser->username}{$actfolder}/{$target}";
$new ="uploads/{$loggedInUser->username}{$actfolder}/{$newName}";
To explain why:
You are using variables inside a string, which means you will want to tell PHP where the variable ends. Especially when referencing objects or arrays, but also when you are placing variables right next to each other. I'm guessing PHP evaluated your original line to uploads/[Object]->usernamePizza/newname
I don't think you can call object properties in a string as you do.
try replace these lines :
$file = "uploads/".$loggedInUser->username."$actfolder/$target";
$new ="uploads/".$loggedInUser->username."$actfolder/$newName";
You may think about echoing $file and $new to confirm the path is nicely built.
On a side note, I'd recommend to really check the entries because this code can obviously lead to major security issues.

How to reference the current directory name, filename and file contents with RecursiveDirectoryIterator loop?

In the script below, I'm attempting to iterate over the folders and files inside of the $base folder. I expect it to contain a single level of child folders, each containing a number of .txt files (and no subfolders).
I'm just needing to understand how to reference the elements in comments below...
Any help much appreciated. I'm really close to wrapping this up :-)
$base = dirname(__FILE__).'/widgets/';
$rdi = new RecursiveDirectoryIterator($base);
foreach(new RecursiveIteratorIterator($rdi) as $files_widgets)
{
if ($files_widgets->isFile())
{
$file_name_widget = $files_widgets->getFilename(); //what is the filename of the current el?
$widget_text = file_get_contents(???); //How do I reference the file here to obtain its contents?
$sidebar_id = $files_widgets->getBasename(); //what is the file's parent directory name?
}
}
//How do I reference the file here to obtain its contents?
$widget_text = file_get_contents(???);
$files_widgets is a SplFileInfo, so you have a few options to get the contents of the file.
The easiest way is to use file_get_contents, just like you are now. You can concatenate together the path and the filename:
$filename = $files_widgets->getPathname() . '/' . $files_widgets->getFilename();
$widget_text = file_get_contents($filename);
If you want to do something funny, you can also use openFile to get a SplFileObject. Annoyingly, SplFileObject doesn't have a quick way to get all of the file contents, so we have to build a loop:
$fo = $files_widgets->openFile('r');
$widget_text = '';
foreach($fo as $line)
$widget_text .= $line;
unset($fo);
This is a bit more verbose, as we have to loop over the SplFileObject to get the contents line-by-line. While this is an option, it'll be easier for you just to use file_get_contents.

Contingency plan for fopen error in php

I'm writing a PHP app that has a 'control panel' that writes a prefs file with certain variables. On every POST, if the file doesn't exist, it is created. If it does exist, it is unlinked and a new file is touched with the same filename and new variables. This file is then included on another page with displays content based on the variables inside it.
$file = "phpsettings.php";
if (!file_exists($file)) {
touch($file);
$handle = fopen ($file, 'r+');
$str = "<?php \$pref1 = \"$mypref\"; ?>";
} else {
unlink($file);
touch($file);
$handle = fopen ($file, 'r+');
$str = "<?php \$pref1 = \"$mypref\"; ?>";
}
fwrite ($handle, $str);
fclose ($handle);
Is this a safe way of writing preferences, provided this file will be overwritten many times per day? What is a good way of both alerting the user of this control panel if the file wasn't saved correctly, and in that case, what would be a good contingency plan to avoid breaking the page this prefs file is included on short of defining a default set of variables to fill if !(file_exists)?
If you store your settings in an array, you can serialize() them and write to a text file, rather than writing raw php to a php file and including it.
If you're not sanitising your input for those preferences, and say $mypref1 represents someone's name, there's nothing stopping them from filling this out in the form field:
\"; echo \"PWNED
and your resulting PHP will become
<?php \$pref1 = \"$mypref\"; echo \"PWNED\"; ?>
So firstly, storing your preferences in an array and using serialize() is much safer:
$prefs = array('mypref1' => 'somethingorother');
$handle = fopen ($file, 'w');
fwrite($handle, serialize($prefs));
fclose($h);
// example code demonstrating unserialization
$prefs2 = unserialize(file_get_contents($file));
var_dump($prefs == $prefs2); // should output "(bool) true"
In your question, you also mention that if the file does exist, it is unlinked. You can simply truncate it to zero length by passing "w" as the second argument to fopen - you don't need to manually delete it. This should set the mtime anyway, negating the need for the call to touch().
If the values being written to the file are preferences, surely each preference could have a default, unless there are hundreds? array_merge will allow you to overwrite on a per-key basis, so if you do something like this:
// array of defaults
$prefs = array(
'mypref1' => 'pants',
'mypref2' => 'socks',
);
if (file_exists($file)) {
// if this fails, an E_NOTICE is raised. are you checking your server error
// logs regularly?
if ($userprefs = unserialize(file_get_contents($file))) {
$prefs = array_merge($prefs, $userprefs);
}
}
If the issue is that there are heaps, and you don't want to have to initialise them all, you could have a get_preference method which just wraps an isset call to the prefs array.
function get_preference($name, &$prefs) {
if (isset($pref[$name]))
return $pref[$name];
return null;
}
var_dump(get_preference('mypref1', $prefs));
Beyond all of the questions this raises though, the reality is that with your app, in the unlikely event that something does go wrong with the fopen, it should be regarded as a serious failure anyway, and the handful of users you're likely to have making use of this feature are going to be contacting you pretty darn quick if something goes wrong.
It is always better to store your users state in a session and only persist that state when needed.
Why not just use the truncation capabilities of fopen()? I believe instead of "r+", you'll need to pass "w+"... Then if the file exists, it will be truncated, if it doesn't you'll just create a new file. So the code becomes:
$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str);
fclose ($handle);

Categories