I'm trying to create a script where a user can upload a csv file into a table. I got the tutorial from shotdev.com, I'm getting the following errors, what am I doing wrong?
**The following command is not allowed: copy
The following command is not allowed: fopen**
Page1.php
<form action="page2.php" method="post" enctype="multipart/form-data" name="form1">
<input name="fileCSV" type="file" id="fileCSV">
<input name="btnSubmit" type="submit" id="btnSubmit" value="Submit">
</form>
Page2.php
<?
copy($_FILES["fileCSV"]["tmp_name"],"shotdev/".$_FILES["fileCSV"]["name"]); // Copy/Upload CSV
include 'datalogin.php';
$objCSV = fopen("shotdev/".$_FILES["fileCSV"]["name"], "r");
while (($objArr = fgetcsv($objCSV, 1000, ",")) !== FALSE) {
$strSQL = "INSERT INTO customer ";
$strSQL .="(CustomerID,Name,Email,CountryCode,Budget,Used) ";
$strSQL .="VALUES ";
$strSQL .="('".$objArr[0]."','".$objArr[1]."','".$objArr[2]."' ";
$strSQL .=",'".$objArr[3]."','".$objArr[4]."','".$objArr[5]."') ";
$objQuery = mysql_query($strSQL);
}
fclose($objCSV);
echo "Import completed.";
?>
It looks like you're running PHP in safe mode or with certain functions disabled. For security reasons web hosts often disable file commands.
You could discuss your requirements with your web host - some are flexible enough to enable the functions for you if you ask nicely.
Otherwise you'll have to achieve it without using the disabled file commands. One way would be to create a textarea in an HTML form in which you paste the CSV. SUbmit it to your PHP script which then runs the MySQL import.
Hope that helps
This seems to be a limitation imposed by the hosting provider (they seem to have put fopen() and copy() on the list of disabled functions, which is rather silly), in which case you probably can't do anything about it except ask the provider to relax the restriction.
Generally though, you're not handling the uploaded files properly using move_uploaded_file(). Use it as shown in the example in the manual link.
Related
How to open a specific folder in file explorer using PHP, I already tried some code but it just directing to random folder. Please help me.
I have try some code
if(empty($_POST['importdata'])) {
//Bahagian Kekotak Papar Button Import -mula-
echo '<form action = "" method="POST" name="upload_excel" enctype
="multipart/form-data">';
echo '<fieldset>
<legend>Jadual Import Data Pelajar</legend>
<label>Pilih Fail (CSV) </label>
<input type ="file" name="file" id="file">
<input id="buttonon" type = "submit" name="importdata" value="UPLOAD &
IMPORT"></fieldset>';
echo '</form>';
}else{
$filename=$_FILES["file"]["tmp_name"];
if($_FILES["file"]["size"]>0) { //jika ada fail CSV
//jika fail CSV telah dipilih
$file = fopen($filename,"r");
while (($getData = fgetcsv($file, 1000, ",")) !== FALSE)
{
}
(this should be a comment, but its too long)
Reading the manual is always a good place to start.
Allowing user direct access to write files on your webserver is inherently very dangerous. The way PHP implements file uploads mitigates many of the risks.
How to open a specific folder in file explorer using PHP
The sentence makes no sense.
Files exist in folders, not the other way around. Do you really want PHP to open up (Micorosf) File explorer showing the directory containing a nominated file? Do you mean to create a copy by "uploading" it from your client? Your code example does not use nominated files / does not attempt to invoke other programs on the host.
it just directing to random folder
No. File uploads always go to the location nominated in your PHP.ini. If no directory is nominated, PHP puts the files in your system temp directory (as determined from your environment variables). And you can determine that location from dirname($_FILES["file"]["tmp_name"])
I am using a simple file operation on the PHP in order to edit the config file for network interface on CentOS 6.7(/etc/sysconfig/network-scripts/ifcfg-eth0
), after change in any value and save into the config file and try to restart the network interface i get this error:
does not seem to be present, delaying initialization.
[FAILED]
my PHP code is this:
<?php
// configuration
$file = '/etc/sysconfig/network-scripts/ifcfg-eth0';
// check if form has been submitted
if (isset($_POST['text']))
{
// save the text contents
file_put_contents($file, $_POST['text']);
// redirect to form again
header('Location: network.php');
exit();
}
// read the textfile
$text = file_get_contents($file);
?>
<!-- HTML form -->
<form action="" method="post">
<textarea style="width:50%; height:50%;" name="text"><?php echo htmlspecialchars($text) ?></textarea>
<input type="submit" />
<input type="reset" />
</form>
i need manually called the network script by command setup and do a modification in the device setting and save then i will be able to restart the network interface. appreciate if anyone help me why this issue happen while if i open the config file and edit it manually it wouldn't cause this issue.
It's most likely that the user name the server runs as (by default apache on most Red Hat-based distributions) doesn't have permission to write to/etc/sysconfig/network-scripts/ifcfg-eth0.
You should check the return values of:
file_put_contents($file, $_POST['text']);
From http://php.net/manual/en/function.file-put-contents.php
This function returns the number of bytes that were written to the file, or FALSE on failure.
I presume this script will only be run by your or trusted colleagues given that there's no validation of the user input. Indentation would also make the PHP code more readable.
I have found many "partial" answers to questions similar to this, but I'm new to PHP and MySQL and there doesn't seem to be one nice big coherent answer out there; What I'm trying to do is this:
Get all the data from a MySQL table called "producers".
Have the user select a filename/'save as' location on their local machine.
PHP / MySQL / HTML gets the data and writes to it as a CSV file.
Parts 1 and 3 are easy; but getting a way for the user to select a file location/filename seems to be nigh on impossible. It's simple in HTML for a user to select a file for upload, so why is it so hard for me to find a way for a user to select a "save" location/name? Surely this is not a security risk - downloading from a server is far less of a security risk than uploading something to a server.
I'd like to be able to use the nice and simple MySQL method, but I don't know how to just send this command from PHP to MySQL; just putting it in a mysqli_query doesn't seem to do anything:
SELECT prodCompany,prodPhone,prodFirstname FROM producers
INTO OUTFILE '/Users/me/Desktop/file.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(this method works fine from within phpMyAdmin).
So I've gone for the clunky step by step PHP method for now, which works, but obviously only ever saves "file.csv" to my desktop. I have read the odd mention of MIME types, but I'm not sure how this could help me and how to implement it.
All I want is to trigger a file selector dialog box, to get that filepath/name into the $filename variable. But after a couple of days of frustration, I cannot find anything that works. Any help or suggestions would be greatly appreciated!
Paul
The PHP that saves to that one file:
<?php
// Create connection
$con=mysqli_connect("xxxxxxxxx","xxxxxxxxx","xxxxxxxxxxxxxx","xxxxxxxxxx");
// Check connection
if (mysqli_connect_errno())
{ echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
$filename = '/Users/me/Desktop/file.csv';
$headers = array('prodCompany', 'prodPhone', 'prodFirstname');
$handle = fopen($filename, 'w');
fputcsv($handle, $headers, ',', '"');
$sql = mysqli_query($con, 'SELECT * FROM producers');
while($results = mysqli_fetch_array($sql)) {
$row = array(
$results['prodCompany'],
$results['prodPhone'],
$results['prodFirstname']
);
fputcsv($handle, $row, ',', '"');
}
fclose($handle);
?>
Okay, the concept being you want to generate a csv and have the user save it.
Form to get file name
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Example</title>
</head>
<body>
<form name="test" action="csv_gen.php" method="post">
<label for="filename">File name </label>
<input type="text" name="filename" id="filename" />
<input type="submit" name="submit" value="go get file" />
</form>
</body>
</html>
Script to process and force csv download
<?php
if($_POST) {
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='.$_POST['filename'].'.csv');
//replace this with whatever generates your csv and print it
echo "field1,field2,field3,field4,field5\n";
}
?>
This will do the force download. With newer browsers that have a default download location, such as Chrome, this will download the file immediately using whatever file name a user enters into the form field. They would then open that location and move the file. That is pretty standard browser functionality that I wouldn't try to overwrite. It might confuse people that have a default location set for downloads.
Hopefully that helps get you started.
I recently ran into a similar problem in a one file php app where all forms submit to the same index.php. After submitting the form, I did the following:
Re-fetched the database results
Used fopen to create a file called 'out.csv' somewhere on the server
Wrote each row of the result set to out.csv
Redirected to out.csv with: header("Location: relative_path_to_csv/out.csv");
The default save dialog appears the same way it would if you were to make a link to the file and click on it.
The drawback is that if it's called concurrently by multiple users, that same 'out.csv' would be overwritten by others. The solution to that is to use a unique identifier for the file name and have some process to periodically clean out the csv directory (cron job).
So im here trying to learn more php and... trying to add an image that a user would upload(an avatar) to the server via move_uploaded_file...oh and im on WAMP right now fyi.
the book im reading ...long story short, the example shown doesnt work. Ive Googled around and literally copy pasted a few relavant examples ive found and still....well to be clear, be it that i wrote it or from the net, i can upload the image name (along with other values) to tables on the db i have set up but the image itself doesn't move to the directory I've set up for it.
I've stripped all my apps code to a simple table and simple php to make sure nothing was conflicting etc, and still nada.
here is my html:
<form method="post" action="testUpload.php" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="32768" >
<table summary="guitarwars lesson" width="500">
<tr>
<td>load picture:</td>
<td><input type="file" name="screenshot" id="screenshot" ></td>
</tr>
<tr>
<td><input type="submit" name="submit" action="submit"></td>
</tr>
</table>
</form>
here is my php:
<?php
$screenshot = $_FILES['screenshot']['name'];
//$destination = "images/user_avatars/$screenshot";
$insertValues = "INSERT INTO testdb(screenshot) VALUES ('$screenshot')";
//---declare connection.
$connect2db = mysqli_connect('127.0.0.1','root','pass','dbname');
if(!$connect2db){
die("Sorry but theres a connection to database error" . mysqli_error);
} else {
//pg intro mssg
echo ' <span style="font-size:25px; color:green;"> --- Link Established with Database ---.<span/><br/><br/>';
}
// put into db.
if(!empty($screenshot)) {
$insertData = mysqli_query($connect2db, $insertValues);
echo 'data submitted. thank you';
move_uploaded_file ($_FILES['screenshot']['tmp_name'],"images/user_avatars/{$screenshot}");
echo 'IMAGE UPLOAD COMPLETE';
}
mysqli_close($connect2db);
?>
now i dont get an error...i actually get the echo "image upload complete" part...
and like i said, with the app code, i get multiple values AND the image name going through and being saved onto the db, but the image itself being moved from temp to my location is a no go.
any tips links, etc i gladly appreciate.
Thank you in advance.
If that's code from your book, then throw the book out and burn it as fast as you can.
a) You're wide open to SQL injection attacks. Any decent PHP tutorial that shows how to deal with databases should START with sql injection attack mitigation strategies.
b) Your connection-failed error uses mysqli_error, which is an undefined constant. You probably want mysqli_error(), which is a function call
c) The code assumes the upload completed successfully. Uploads can/will fail at the drop of a hat, so NOT checking for errors is the fast road to hair-pulling. At minimum the script should have something like
if ($_FILES['screenshot']['error'] !== UPLOAD_ERR_OK) {
die("Upload failed with error code " . $_FILES['screenshot']['error']);
}
Those error codes are defined here.
d) Your code is using the user-supplied filename to store the file onto the sever. Nothing says that a malicious user can't hack the filename to include path information, so your code is actually allowing that nasty user to scribble on ANY file on your server which the webserver process has write access to. This is BAD
e) Your code also assumes the file move succeeded, without checking for errors. It should have at mininum
$status = move_uploaded_file(...);
if (!$status) {
die("Move failed!");
}
or something similar.
f) Your code assumes that all the database queries succeeded. Even if your query string is 100% perfectly formed (yours aren't, see (a) above), queries can fail for any number of other reasons. At bare mininum you should have:
$result = mysql_query(...) or die(mysqli_error());
As a start you could add
if(!move_uploaded_file(...))
die('error');
if you replace
move_uploaded_file ($_FILES['screenshot']['tmp_name'],"images/user_avatars/{$screenshot}");
echo 'IMAGE UPLOAD COMPLETE';
with
if (move_uploaded_file ($_FILES['screenshot']['tmp_name'],"images/user_avatars/{$screenshot}")) {
echo 'IMAGE UPLOAD COMPLETE';
}
you would then get the echo if it was successful
Try to supply the absolute path:
move_uploaded_file ($_FILES['screenshot']['tmp_name'],"/path/to/images/user_avatars/{$screenshot}");
I've worked with a few scripts to begin uploading files on my development machine. Problem is, despite the expected ease of this operation, Apache seems to time-out whenever I try to upload an image. Uploading is set to On and the tmp directory is set in php.ini.
I tried uploading the main gif from Google, an 8.36KB image. It should be fine and well within the limits to PHPs uploading capabilities.
Here is a copy of the script. There should be an easy fix. As requested, I changed the tilde to an actual directory.
<?php
if (!isset($_GET['upload'])) { ?>
<form method="post" action="index.php?upload=true" enctype="multipart/form-data">
<input type="file" name="file" class="form">
<input name="submit" type="submit">
</form>
<? } else if (isset($_GET['upload']) && $_GET['upload'] == 'true') {
$url = $_FILES['file']['name'];
$move = move_uploaded_file($_FILES['file']['tmp_name'], "/Users/<username>/Sites/file.jpg");
if ($move) {
echo "Success!";
} else {
echo "Err..."
}
} ?>
Thanks,
Dan
EDIT:
I fixed it, with help from a few of the answers, to one of which I will mark.
A few things here were causing this behavior.
Permissions on the images directory were not set to allow the _www user to access it. A chmod -R 777 images seemed to fix it, as well as a sudo chown _www images.
The form output may have been corrupting the PHP script itself. As suggested, an ECHO <<< ...END helped, I think.
What is it that leads you to believe that Apache is timing out rather than, say, outright failing in some way? Because what leaps out at me is that you're trying to move the file to ~/file.jpg, which I'm nearly certain will not work; ~ is a construct that only normally has meaning inside shells, unless one of PHP's freakish obscure features is processing it in contexts like this. Anyway, try putting the actual directory.
This is more than likely an issue with the size of the file and/or a permission issue between the Apache user and the directory specified. For instance make sure the Apache instance is not running under user (nobody).
Comment to chaos:
He is right the tilde (~) can cause issues, but would probably not cause a timeout; it would display a warning. Even if it does work on your system it would probably deposit the file into an unexpected directory or run into some issues if the Apache user (ie www) does not have a valid home directory set.
If the issue is filesize, add the following lines to your php.ini file and it should work:
upload_max_filesize = 500M ;
post_max_size = 500M ;
PHP by default has a 30 second timeout on the page. So if your upload takes longer than 30 seconds it will fail. Set the timeout either in your php.ini or put the following code at the top of the file.
ini_set(max_execution_time, 90);
The second argument represents the time in seconds before the page will timeout. Set it to whatever time you feel is appropriate. Also, chaos is correct in that '~' is a construct that commonly has meaning only inside shells.
Re: http://ca2.php.net/manual/en/ini.list.php
EDIT:
The problem is that you reopened the tag in the middle of a conditional. Trying your code I get a syntax error. It's strange that you were able to see any web form. This is the fixed code (that works for me).
<?php
if (!isset($_GET['upload'])) {
ECHO <<<END
<form method="post" action="index.php?upload=true" enctype="multipart/form-data">
<input type="file" name="file" class="form">
<input name="submit" type="submit">
</form>
END;
} else if (isset($_GET['upload']) && $_GET['upload'] == 'true') {
$url = $_FILES['file']['name'];
$move = move_uploaded_file($_FILES['file']['tmp_name'], "/Users/<username>/Sites/file.jpg");
if ($move) {
echo "Success!";
} else {
echo "Err...";
}
} ?>