I have a perl script which takes input as a file and return results in text files. I want to use file as input, which is uploaded by user through php page. For that what should I do? I have PHP 5.3.14 and ActivePerl 5.14.x.
In PHP, when a file is uploaded, it is first placed in a temporary location. You can move it to another location using move_uploaded_file():
http://php.net/manual/en/function.move-uploaded-file.php
Then, you can call your Perl script in a variety of ways, which are outlined here:
How can I call a Perl script from PHP?
So, let's say you are using the low-level method of using the exec() function, and the file is uploaded in a file upload field with name "userfile", you might use something like this:
$perlCommand = // ... something, e.g. from config ...
$workingPath = // ... something, e.g. from config ...
$filename = $workingPath . $_FILES['userfile']['name']
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $filename)) {
$output = array();
$return = 0;
exec($perlCommand . ' ' . $filename, $output, $return);
// Do something with $output and / or $return values
}
Note that this assumes that the Perl script takes the name of the file as an argument. It might be that it reads the file from standard input, it wasn't clear from the question. Obviously if it is the latter then it will be a bit different, again depending on the method you use to call Perl.
Thanks #leftclickben
I've solved the problem. I used a form to get file from user and then saved the filename to an argument $file.
Then I passed $file to Perl script using
$result = shell_exec("path\to\perl.pl" $file);
echo $result;
$file passed to perl.pl as an array named $ARGV[0]
#!usr/bin/perl
$filename = $ARGV[0];
open(HDL, $filename) or die "file not available, restart program\n";
Related
I have a function like this:
fitImageSizeAndSave($_FILES["imageToUpload"]["tmp_name"], $target_file) { ... }
That function works well. The first argument is $_FILES["imageToUpload"]["tmp_name"]. Ok, it's good when an user upload an image from his local computer. But sometimes he enters a external link and I get that image like this:
$image = file_get_contents($_POST['external_link']);
How can I make $image like $_FILES["imageToUpload"]["tmp_name"] for passing it to the function?
use file_put_contents() and then reference the temporary file that you've just put the data into
#Martin Sounds a great idea, may you please add an answer? –
$_FILES["imageToUpload"]["tmp_name"] is simply a string to a file location on the server, it is not a resuorce in itself.
$filePathLocation = $_SERVER['DOCUMENT_ROOT']."/some-temporary/file/storage";
$imageData = file_get_contents($_POST['external_link']);
if($imageData){
file_put_contents($imageData, $filepathLocation);
}
else {
$filepathLocation = $_FILES["imageToUpload"]["tmp_name"];
}
fitImageSizeAndSave($filepathLocation, $target_file) { ... }
The above, step by step:
Set a temporary storage location; possibly based on microtime() or something unique (database Id, if relevant) to limit different processes overwriting the same file path.
get the contents of the $_POST file URL. save to a string variable.
Check if variable is loaded ok; else use uploaded temporary file location THIS IS FOR ILLUSTRATION ONLY - You should have a more complete process for checking which data to use and the validity of said data already set up in your script.
Send this variable to your custom function, knowning it is populated with one or the other of the possibilities above.
The below is the PHP script to get image from url and save into your location machine or into own server
$imageurl ='http://i.ndtvimg.com/i/2015-08/mahesh-babu_630x450_81440064359.jpg';
$content = file_get_contents($imageurl);
if(file_put_contents('imagefolder/randomImageName.jpg', $content)){
echo "File uploaded through URL";
}else{
echo "File not uploaded...";
}
Good Day All
I have a .php file which I want to edit via fopen() and file_get_content() functions. However, my file contains some php codes as well and I managed to get the content out of my file but without the php part. Also, I have tried the eval() (I know it's not suggested!) function with same results. I was wondering if there could be a way to get whatever is inside that file regardless wether it's text or codes.
Thanks
Here is the code I used:
public function editwarning()
{
$filename = "http://www.parkho.ir/admin/templates/pm/email_warning.php";
$content = file_get_contents($filename);
echo $content;
}
You have two options:
1) pass the file PATH to the $filename var:
$filename = "/var/www/app/email_warning.php"; // <--- replace /var/www/app for your path
2) Or You need to use htmlentities():
<?php
$content = htmlentities(file_get_contents($filename));
echo $data;
I have a config.inc file in a web application that I am building. It contains an array with configuration values for things like the MySQL database, etc. I would like these to be entered by using a simple form, that asks for the server, login/password for the database, etc, then these get written to the configuration file.
Is there a preferred method of doing this? I am not sure how to write to a file, and update an array.
You just want writing, correct? Is it a serialized array or is it parsed?
One way to read a config file is parse_ini_file(). I wouldn't necessarily call it preferred, but it's a method. You'd still need to write the file.
Another way would to write a "config.inc.php" and just include it in, to write it you'd just output actual PHP code (e.g. $var = "myval";).
This is a way you could write a simple "output" function that took an array of configuration values and output them as name=value, assuming $config was an associative array.
foreach ($config as $name => $value) {
$output .= $name . '=' . $value . "\n";
}
if (!file_put_contents($filename, $output)) {
die("Error writing config file.");
}
There's a lot of decent ways to do it. It's really based on your requirements. Does it need to be in a specific format or do you have leeway?
It is not recommended to modify PHP configuration files via your application, you should use CSV files or a database table.
In case you want to save it in a CSV file then I suggest you keep a CSV file for each configuration type (e.g CSV file for database configurations) and always overwrite the previous one using file_put_contents
Save data example:
$csvStructure = array("dbUser","dbPassword","dbHostname","dbPort"); // array used for both loading data and saving it
$csvData = array();
foreach ($csvStructure as $field) {
$csvData[] = $_POST[$field]; // so it'd get $_POST["dbUser"],$_POST["dbPasword"], etc..
}
file_put_contents("filename",implode("\t",$csvData));
Load data example:
$csvStructure = array("dbUser","dbPassword","dbHostname","dbPort"); // array used for both loading data and saving it
$dbConfig = array();
$csvData = explode("\t",file_get_contents("filename"));
foreach ($csvStructure as $key => $field) { // $key would have the location of the requested field in our CSV data (0,1,2, etc..).
$dbConfig[$field] = $csvData[$key]; // populate $dbConfig["dbUser"],$dbConfig["dbPasword"], etc..
}
I believe using an ini file is a wise option, because user, password, schema, paths, etc. are things that usually will be modified by hand, so using var_export isn't because modifying it by hand it's not so clean and may crash your application if you make a mistake in the PHP syntax.
But parsing big ini files can be expensive, so it would be OK to cache the ini with var_export() or serlialize(). It's a better choice, I think, and read the ini only when the cache file doesn't exists.
PHP has a dedicated function for this, its called var_export();
Just do:
file_put_contents("config.php",var_export($config,true));
Well, to write a file, fwrite() php function does exactly what you want. From its PHP.NET documentation page (see example below).
Now, on the question as to what to output to that file - I'm assuming that file will have to be included as a configuration .php file into the rest of the project. I'm imagining you'll do something like this - where you're creating strings with PHP code on the fly, based on the submitted form:
$strDatabaseConfig = "\$databaseConfig = array('" . $_POST['login'] . "," . $_POST['password'] . "');";
And here's the snippet for fwrite:
$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";
}
Here's one way: wp-admin/setup-config.php from WordPress.
I prefer to have a file with a bunch of define statements.
These are constants globally available (and of course immutable) which is what you need for configuration settings.
Constants offer better memory management and efficiency in reading as they don't need the extra memory required by a variable so that it can be changed.
Let's say your config.inc file looks like this:
$config = array(
'blah' => 'mmm',
'blah2' => 'www',
//...
);
You want to update it, so you create a simple form, fill text fields with current values. PHP script that overwrites current configuration could looks like this:
$newConfig = ...; // data from form - of course validate it first
$config = ...; // data from config.inc
$config = array_merge($config, $newConfig);
file_put_contents('config.inc', '<?php $config = ' . var_export($config, true));
And you're done.
I've made an image upload script using the move_uploaded_file function. This function seems to overwrite any preexisting file with the new one. So, I need to check if the target location already has a file. If it does then I need to append something to the filename(before the extension so that the file name is still valid) so the filename is unique. I'd like to have the change be minimal instead of something like appending the datetime, if possible.
How can I do this with PHP?
When uploading files I will nearly always rename them. Typically there will be some kind of database record for that file. I use the ID of that to guarantee uniqueness of the file. Sometimes I'll even store what the client's original filename was in the database too but I'll never keep it or the temporary name because there is no guarantee that information is good, that your OS will support it or that it's unique (which is your issue).
So just rename it to some scheme of your own devising. That's my advice.
If you don't have any database reference, then you could use file_exists() for this but there's no guarantee that between the time of checking if something exists and moving it that something else won't use that same filename that you'll then overwrite. This is a classic race condition.
http://us3.php.net/manual/en/function.file-exists.php
Don't use file_exists() for the reason that it returns true (on *nix systems at least, since directories are specialized files) if the value is a directory. Use is_file() instead.
For example, say something fails and you have a string like:
$path = "/path/to/file/" . $file; // Assuming $file is an empty value, if something failed for example
if ( true === file_exists($path) ) { echo "This returns true"; }
if ( true === is_file($path) ) { echo "You will not read this"; }
It's caused a few problems in the past for me, so I always use is_file() rather than file_exists().
I use date and time functions to generate a random file name based on the time of upload.
Let's assume you are submitting a file from a form where you have an input named incomingfile like this:
<input type="file" id="incomingfile" name="incomingfile" />
First of all I use to "depure" the filename and copy it from the default temporary directory to a temporary directory. This is necessary to deal with special characters. I had troubles when I didn't adopt this practice.
$new_depured_filename = strtolower(preg_replace('/[^a-zA-Z0-9_ -.]/s', '_', $_FILES["incomingfile"]["name"]));
copy($_FILES["incomingfile"]["tmp_name"], 'my_temp_directory/'.$new_depured_filename);
With the following piece of code I check if the file exists, if so, I find a new name and finally copy it. For example if I want to write a file called myimage.jpg and it already exists I rename the pending file to myimage__000.jpg. If this exists as well I rename the pending file to myimage__001.jpg and so on until I find a non-existing filename.
$i=0; // A counter for the tail to append to the filename
$new_filename = $new_depured_filename;
$new_filepath='myfiles/music/'.$new_filename;
while(file_exists($new_filepath)) {
$tail = str_pad((string) $i, 3, "0", STR_PAD_LEFT); // Converts the integer in $i to a string of 3 characters with left zero fill.
$fileinfos = pathinfo($new_filepath); // Gathers some infos about the file
if($i>0) { // If we aren't at the first while cycle (where you have the filename without any added strings) then delete the tail (like "__000") from the filename to add another one later (otherwise you'd have filenames like myfile__000__001__002__003.jpg)
$previous_tail = str_pad((string) $i-1, 3, "0", STR_PAD_LEFT);
$new_filename = str_replace('__'.$previous_tail,"",$new_filename);
}
$new_filename = str_replace('.'.$fileinfos['extension'],"",$new_filename); // Deletes the extension
$new_filename = $new_filename.'__'.$tail.'.'.$fileinfos['extension']; // Append our tail and the extension
$new_filepath = 'myfiles/music/'.$new_filename; // Crea il nuovo percorso
$i++;
}
copy('my_temp_directory/'.$new_depured_filename, $new_filepath); // Finally we copy the file to its destination directory
unlink('my_temp_directory/'.$new_depured_filename); // and delete the temporary one
Used functions:
strtolower
preg_replace
copy
file_exists
str_pad
pathinfo
str_replace
unlink
To check if a file exists, you can use the file_exists function.
To cut the filename, you can use the pathinfo function.
I use
$file_name = time() . "_" . $uploaded_file_name;
I need to convert some files to PDF and then attach them to an email. I'm using Pear Mail for the email side of it and that's fine (mostly--still working out some issues) but as part of this I need to create temporary files. Now I could use the tempnam() function but it sounds like it creates a file on the filesystem, which isn't what I want.
I just want a name in the temporary file system (using sys_get_temp_dir()) that won't clash with someone else running the same script of the same user invoking the script more than once.
Suggestions?
I've used uniqid() in the past to generate a unique filename, but not actually create the file.
$filename = uniqid(rand(), true) . '.pdf';
The first parameter can be anything you want, but I used rand() here to make it even a bit more random. Using a set prefix, you could further avoid collisions with other temp files in the system.
$filename = uniqid('MyApp', true) . '.pdf';
From there, you just create the file. If all else fails, put it in a while loop and keep generating it until you get one that works.
while (true) {
$filename = uniqid('MyApp', true) . '.pdf';
if (!file_exists(sys_get_temp_dir() . $filename)) break;
}
Seriously, use tempnam(). Yes, this creates the file, but this is a very intentional security measure designed to prevent another process on your system from "stealing" your filename and causing your process to overwrite files you don't want.
I.e., consider this sequence:
You generate a random name.
You check the file system to make sure it doesn't exist. If it does, repeat the previous step.
Another, evil, process creates a file with the same name as a hard link to a file Mr Evil wants you to accidentally overwrite.
You open the file, thinking you're creating the file rather than opening an existing one in write mode and you start writing to it.
You just overwrote something important.
PHP's tempnam() actually calls the system's mkstemp under the hood (that's for Linux... substitute the "best practice" function for other OSs), which goes through a process like this:
Pick a filename
Create the file with restrictive permissions, inside a directory that prevents others from removing files it doesn't own (that's what the sticky-bit does on /var/tmp and /tmp)
Confirms that the file created still has the restrictive permissions.
If any of the above fails, try again with a different name.
Returns the filename created.
Now, you can do all of those things yourself, but why, when "the proper function" does everything that's required to create secure temporary files, and that almost always involves creating an empty file for you.
Exceptions:
You're creating a temporary file in a directory that only your process can create/delete files in.
Create a randomly generated temporary directory, which only your process can create/delete files in.
Another alternative based on #Lusid answer with a failover of max execution time:
// Max exectution time of 10 seconds.
$maxExecTime = time() + 10;
$isUnique = false;
while (time() !== $maxExecTime) {
// Unique file name
$uniqueFileName = uniqid(mt_rand(), true) . '.pdf';
if (!file_exists(sys_get_temp_dir() . $uniqueFileName)){
$isUnique = true;
break;
}
}
if($isUnique){
// Save your file with your unique name
}else{
// Time limit was exceeded without finding a unique name
}
Note:
I prefer to use mt_rand instead of rand because the first function use Mersenne Twister algorithm and it's faster than the second (LCG).
More info:
http://php.net/manual/en/function.uniqid.php
http://php.net/manual/en/function.mt-rand.php
http://php.net/manual/en/function.time.php
Consider using an uuid for the filename. Consider the uniqid function.
http://php.net/uniqid
You could use part of the date and time in order to create a unique file name, that way it isn't duplicated when invoked more than once.
I recomend you to use the PHP function
http://www.php.net/tempnam
$file=tempnam('tmpdownload', 'Ergebnis_'.date(Y.m.d).'_').'.pdf';
echo $file;
/var/www/html/tmpdownload/Ergebnis_20071004_Xbn6PY.pdf
Or
http://www.php.net/tmpfile
<?php
$temp = tmpfile();
fwrite($temp, "writing to tempfile");
fseek($temp, 0);
echo fread($temp, 1024);
fclose($temp); // this removes the file
?>
Better use Unix timestamp with the user id.
$filename='file_'.time().'_'.$id.'.jepg';
My idea is to use a recursive function to see if the filename exists, and if it does, iterate to the next integer:
function check_revision($filename, $rev){
$new_filename = $filename."-".$rev.".csv";
if(file_exists($new_filename)){
$new_filename = check_revision($filename, $rev++);
}
return $new_filename;
}
$revision = 1;
$filename = "whatever";
$filename = check_revision($filename, $revision);
function gen_filename($dir) {
if (!#is_dir($dir)) {
#mkdir($dir, 0777, true);
}
$filename = uniqid('MyApp.', true).".pdf";
if (#is_file($dir."/".$filename)) {
return $this->gen_filename($dir);
}
return $filename;
}
Update 2020
hash_file('md5', $file_pathname)
This way you will prevent duplications.