I allow users to submit files into the database on my website. But every time a file is submitted, i get these error messages
( ! ) Warning: file_get_contents() expects parameter 1 to be a valid path, array given in C:\wamp64\www\MT\developerUpload.php on line 8
( ! ) Warning: trim() expects parameter 1 to be string, array given in C:\wamp64\www\MT\developerUpload.php on line 9
But I was told that "file_get_contents" is the way you send the file contents to the database. Without the "file_get_contents" it sends perfectly but with it, it gives me those error messages and I am not sure why. So what i want to do is, submit the file using the "file_get_contents" so later on i can display the content on the users page. Here is my code
PHP
$query = "INSERT INTO pack_screenshots(pack_id, file_name, file_tmp)VALUES(:packid, :file_name, :file_tmp)";
$stmtFileUpload = $handler->prepare($query);
$errors = array();
foreach($_FILES['file']['tmp_name'] as $key => $error){
if ($error != UPLOAD_ERR_OK) {
$errors[] = $_FILES['file']['name'][$key] . ' was not uploaded.';
continue;
}
$file_tmp = file_get_contents($_FILES['file']['tmp_name']);
$file_name = addslashes(trim($_FILES['file']['name']));
try{
$stmtFileUpload->bindParam(':packid', $packid, PDO::PARAM_STR);
$stmtFileUpload->bindParam(':file_name', $file_name, PDO::PARAM_STR);
$stmtFileUpload->bindParam(':file_tmp', $file_tmp, PDO::PARAM_STR);
$stmtFileUpload->execute();
$dir = "devFiles";
if(is_dir($dir)==false){
mkdir($dir, 0700);
}
if(is_file($dir.'/'.$file_name)==false){
move_uploaded_file($file_tmp,$dir.'/'.$file_name);
}else{
$_SESSION['invalid'] = true;
header("Location: developer_invalid.php");
exit;
}
$_SESSION['thankyou'] = true;
header("Location: developerUpload_thankyou.php");
exit;
}catch(PDOException $e){
$errors[] = $file_name . 'not saved in db.';
echo $e->getMessage();
}
}
Your problem is you have no keys associated with the 2 lines giving you an error (and probably elsewhere in your code), therefore they are arrays (as you are not selecting a specific key).
You need to associate the keys to the $_FILES array.
$file_tmp = file_get_contents($_FILES['file']['tmp_name'][$key]);
$file_name = addslashes(trim($_FILES['file']['name'][$key]));
Since you are using multiple uploads so you have to assign keys to them before proceed.
file_get_contents() and trim() accepts string here you pass array in it without assigning key.
Try this:
$file_tmp = file_get_contents($_FILES['file']['tmp_name'][$key]);
$file_name = addslashes(trim($_FILES['file']['name'][$key]));
Related
I have a very weird problem with php and I can't find any explanation for it.
I want to add this line of code to grab extension from the sent file:
$extension = array_pop( explode( "." , $_FILES["myFiles"]["name"][$key]);
but if i do so php doens't send a respond although the file is saved successfully. If I simply delete this line and hardcode ".jpg" instead $extension it sends the response as expected.
<?php
$response = array();
if (isset($_FILES)) {
foreach ($_FILES["myFiles"]["tmp_name"] as $key => $value) {
$user = $_POST["user"];
// when i add the line below it deosn't send the response!
$extension = array_pop( explode( "." , $_FILES["myFiles"]["name"][$key]) );
move_uploaded_file($value, "uploads/$user.$extension");
};
$response["msg"] = "image has been uploaded";
} else {
$response["msg"] = "selcect an image";
}
echo json_encode($response);
array_pop takes argument by reference. You can't provide argument directly from another function to array_pop.
Instead in your case you should do this:
$parts = explode("." , $_FILES["myFiles"]["name"][$key]);
$extension = array_pop($parts);
But! You should NEVER trust client's data, even if it's just a file extension. It is better to check extension itself (is it jpg, png, svg, gif), also check if the file is really an image, check size of that image, etc...
On my website, I allow users to submit files and they are sent to the database and a file directory, devFiles, I created. It sends to the database fine, but when i send it to the directory, it never sends and i get my error message i created to see if it sends or not. I believe the problem is with the
if(is_file($dir.'/'.$file_name)==false){
//code...
}
but i tried change the condition but it didn't work. So what i want to do is, send the file that was submitted to the file directory on hand that was created. Here is my code
PHP
$query = "INSERT INTO pack_screenshots(pack_id, file_name, file_tmp)VALUES(:packid, :file_name, :file_tmp)";
$stmtFileUpload = $handler->prepare($query);
$errors = array();
foreach($_FILES['file']['tmp_name'] as $key => $error){
if ($error != UPLOAD_ERR_OK) {
$errors[] = $_FILES['file']['name'][$key] . ' was not uploaded.';
continue;
}
$file_tmp = file_get_contents($_FILES['file']['tmp_name'][$key]);
$file_name = addslashes(trim($_FILES['file']['name'][$key]));
try{
$stmtFileUpload->bindParam(':packid', $packid, PDO::PARAM_STR);
$stmtFileUpload->bindParam(':file_name', $file_name, PDO::PARAM_STR);
$stmtFileUpload->bindParam(':file_tmp', $file_tmp, PDO::PARAM_STR);
$dir = "devFiles";
if(is_dir($dir)==false){
mkdir($dir, 0700);
}
if(is_file($dir.'/'.$file_name)==false){
if(!move_uploaded_file($file_tmp,$dir.'/'.$file_name)){
die("File didn't send!");
}
}else{
$_SESSION['invalid'] = true;
header("Location: developer_invalid.php");
exit;
}
$stmtFileUpload->execute();
$_SESSION['thankyou'] = true;
header("Location: developerUpload_thankyou.php");
exit;
}catch(PDOException $e){
$errors[] = $file_name . 'not saved in db.';
echo $e->getMessage();
}
}
PHP Documentation bool move_uploaded_file ( string $filename , string $destination )
You did :
move_uploaded_file($file_tmp,$dir.'/'.$file_name)
move_uploaded_file is expecting $file_tmp to be a path to the tmp file but you used
$file_tmp = file_get_contents($_FILES['file']['tmp_name'][$key]);
so $file_tmp is no longer the path but the content it self
So to solve the upload problem just use the tmp file path instead.
if(!move_uploaded_file($_FILES['file']['tmp_name'][$key],$dir.'/'.$file_name)){
Also, you should remove addslashes() on the file name because it could create unexpected results. Instead, you can sanitize the filename using something like this:
$file_name = preg_replace("/[^a-z0-9\.]/", "_", strtolower($_FILES['file']['name'][$key]));
You should also consider adding a random number to the file name so users don't overwrite other users files that have the same name: me.png could be common for an avatar for example. Would be safer to save as
$filename = strtotime("now")."_me.png";
One last thing, using is_file() can also cause problems in certain cases
Note: Because PHP's integer type is signed and many platforms use 32bit integers, some filesystem functions may return unexpected results for files which are larger than 2GB.
use file_exists() instead
I tried to integrate krajee file-input into my existing form. DEMO SITE
When i browse a file from my computer and click upload button (built-in with the plugin), i got this error: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data.
The author of this plugin told me that i have to write valid json response in my php file for this to work but he did not have time to help individual case like mine. So I read the documentation from the website, it has this part:(you can find it on the demo site above)
Sending Data (from server)
Your server method as set in uploadUrl must send data back as a json encoded object. The only key you must send is the error which will be the error message for the upload and will help the plugin to identify error in the file upload. For example the response from server would be sent as {error: 'You are not allowed to upload such a file.'}. Note: The plugin will automatically validate and display ajax exception errors.
IMPORTANT
You MUST send a valid JSON response from your server, else the upload process will fail. Even if you do not encounter any error, you must at least send an empty JSON object {} from your server.
To trap and display a validation error, your JSON response data must include the error key, whose value will be the error HTML markup to display. This is to be setup as mentioned above.
Unfortunately, I can't understand it because I am just a new php learner and this is out of my scope. But I have my php file here, hope some expert can help me to add the json response to it as the documentaion explained above. Thank you very much in advance!
Here is my php file:
<?php
if(isset($_POST["submit"])){
require("../configs/dbconnect.php");
/*Form variable */
$owner = mysql_real_escape_string($_POST["owner"]);
$title = mysql_real_escape_string($_POST["title"]);
$description = mysql_real_escape_string($_POST["description"]);
$city = mysql_real_escape_string($_POST["city"]);
$brand = mysql_real_escape_string($_POST["brand"]);
$marketprice = mysql_real_escape_string($_POST["marketprice"]);
$price = mysql_real_escape_string($_POST["price"]);
$phone = mysql_real_escape_string($_POST["phone"]);
/*** the upload directory ***/
$upload_dir= 'uploads';
/*** numver of files to upload ***/
$num_uploads = 5;
/*** maximum filesize allowed in bytes ***/
$max_file_size = 5000000;
/*** the maximum filesize from php.ini ***/
$ini_max = str_replace('M', '', ini_get('upload_max_filesize'));
$upload_max = $ini_max * 1024;
/*** a message for users ***/
$msg = 'Please select files for uploading';
/*** an array to hold messages ***/
$messages = array();
$err=array();
/*** check if a file has been submitted ***/
if(isset($_FILES['file']['tmp_name']))
{
/** loop through the array of files ***/
for($i=0; $i < count($_FILES['file']['tmp_name']);$i++)
{
// check if there is a file in the array
if(!is_uploaded_file($_FILES['file']['tmp_name'][$i]))
{
$messages[] = 'No file uploaded';
}
/*** check if the file is less then the max php.ini size ***/
//elseif($_FILES['image']['size'][$i] > $upload_max)
//{
// $messages[] = "File size exceeds $upload_max php.ini limit";
//}
// check the file is less than the maximum file size
elseif($_FILES['file']['size'][$i] > $max_file_size)
{
$messages[] = "File size exceeds $max_file_size limit";
}
else
{
//$temp = explode(".", $_FILES["file"]["name"][$i]);
//$extension = end($temp);
//$name[$i] = sha1(microtime()) . "." . $extension;
$name[$i]=$_FILES["file"]["name"][$i];
// copy the file to the specified dir
if(move_uploaded_file($_FILES['file']['tmp_name'][$i],$upload_dir.'/'.$name[$i]))
{
/*** give praise and thanks to the php gods ***/
$messages[] = $name[$i].' uploaded';
$image_path[$i]=$upload_dir.'/'.$name[$i];
}
else
{
/*** an error message ***/
$messages[] = 'Uploading '.$name[$i].' Failed';
}
}
}
}
$image_path_string=serialize($image_path);
$sql = "INSERT INTO memberpost(owner, title, description, city, brand, marketprice, price, phone, image) VALUES ('$owner', '$title','$description','$city','$brand','$marketprice','$price','$phone', '" . $image_path_string . "')";
$result = mysql_query($sql) or die ("Could not insert data into DB: " . mysql_error());
if(sizeof($messages) != 0)
{
foreach($messages as $err)
{
echo $err.'<br />';
}
}
}
?>
Your echo i think...
Put your error on any variable then echo json_encode(variable name). That's how to send JSON object.
I wondered if there were a way to check if the filename exists and then to add a number after it, I know this - in a basic for is possible so if someone does it once it'll add 1 after it.
But how would you get it to check if someone has done it more than once? So the first time it would add a 1 then a 2 then a 3 and so on?
$title = $_POST['title'];
$content = $_POST['content'];
$compile = $title. "\r\n" .$content;
$content = $compile;
$path = "../data/" .md5($title). ".txt";
$fp = fopen($path,"wb");
fwrite($fp,$content);
fclose($fp);
$con=new mysqli("###","###_public","###","###");
if (!($stmt = $con->prepare("INSERT INTO `blog_posts` (`post_title`,`post_content`,`post_date`) VALUES (?,?,?)")) || !is_object($stmt)) {
die( "Error preparing: (" .$con->errno . ") " . $con->error);
}
$stmt->bind_param('sss', $_POST['title'], $path, $_POST['date']);
if($stmt->execute()) {
echo "Successfully Posted";
} else {
echo "Unsuccessfully Posted";
}
$stmt->close();
Thanks for any help in advance
The general idea would be like this:
$basefilename = "somefile";
$filename = $basefilename;
$i = 0;
while(file_exists("../data/".$filename.".txt") $filename = $basefilename.(++$i);
Adapt as needed.
You can use something like this:
<?php
if(file_exists($filename)) { // check if the file exists in the first place
$i = 1;
while(file_exists($filename.$i)) { // check if the filename with the index exists. If so, increase the $i by 1 and try again
$i++;
}
rename($filename, $filename.$i); // rename the actual file
} else {
// file did not exist in the first place
}
Do not add strings at the end of file name - you would eventually
hit the OS file name length limit pretty soon. You would also fail
to recognize the last added number, when the string gets too big -
you'd have to parse all the numbers from the beginning.
Use glob() to search for a file name.
Parse the file names found for the number at the end and increment
that number.
Use rename() on the file name and check the return status to
avoid racing conditions.
Generally avoid that - use a database or any other system that
supports atomic operations.
I want to upload images to mysql server using php.
I have created html and sql connectivity but the image upload shows error.
I cant upload the image, it shows error of valid image i.e. you must upload jpeg,bmp,gif; and read/write in directory.
Can any1 help me solving this problem
the php file is
<?php
//Start session
session_start();
//Array to store validation errors
$errmsg_arr = array();
//Validation error flag
$errflag = false;
// Check to see if the type of file uploaded is a valid image type
function valid($file)
{
// This is an array that holds all the valid image MIME types
$valid_types = array("image/jpg", "image/jpeg", "image/bmp", "image/gif");
//echo $file['type'];
if (in_array($file['type'], $valid_types))
return 1;
return 0;
}
// Build our target path full string. This is where the file will be moved do
// i.e. images/picture.jpg
$TARGET_PATH = "image/";
$TARGET_PATH = $TARGET_PATH . basename( $_FILES['image']['name']);
$pimage = $_FILES['image']['name'];
// Check to make sure that our file is actually an image
// You check the file type instead of the extension because the extension can easily be faked
if (!valid($pimage))
{
$_SESSION['ERRMSG_ARR'] = array('You must upload a jpeg, gif, or bmp');
header("Location: admin.php");
exit;
}
// Here we check to see if a file with that name already exists
// You could get past filename problems by appending a timestamp to the filename and then continuing
if (file_exists($TARGET_PATH))
{
$_SESSION['ERRMSG_ARR'] = array('A file with that name already exists');
header("Location: admin.php");
exit;
}
// Lets attempt to move the file from its temporary directory to its new home
if (move_uploaded_file($_FILES['image']['tmp_name'], $TARGET_PATH))
{
// NOTE: This is where a lot of people make mistakes.
// We are *not* putting the image into the database; we are putting a reference to the file's location on the server
$sql = "insert into people (p_category, p_name, p_quantity, p_desc, p_image) values ('$pcategory', '$pname','$pquantity','pdesc', '" . $pimage['name'] . "')";
$result = mysql_query($sql);
//Check whether the query was successful or not
if($result) {
$_SESSION['ERRMSG_ARR'] = array('Product added');;
$_SESSION['MSG_FLAG'] = 0;
session_write_close();
header("location: admin.php");
exit();
}else {
die("Query failed: ".mysql_error());
}
}
else
{
// A common cause of file moving failures is because of bad permissions on the directory attempting to be written to
// Make sure you chmod the directory to be writeable
$_SESSION['ERRMSG_ARR'] = array('Could not upload file. Check read/write persmissions on the directory');
header("Location: admin.php");
exit;
}
?>
I think
$pimage = $_FILES['image']['name'];
should be
$pimage = $_FILES['image'];
You probably missed this because your code is quite inconsistent - sometimes you use $pimage, while elsewhere you reference the $_FILES array directly. This makes it harder to maintain should the file field's name change. You could also type hint the valid() function to make PHP complain if $file isn't an array:
function valid(array $file) { ... }
What level of error reporting do you have set? It would highlight errors like trying to access undefined array keys.
See you are passing the image type in the line if (!valid($pimage))
But in the valid() function you are again trying to get the type of image $file['type'].
What George said should also work, but since you are making variables for the image type $ptype and name $pimage, you can use them itself.
So the changes should be $file['type'] becomes $file and $file['type'] & in the insert query $pimage['name'] becomes $pimage
I'm sure this solves it, Bahua ;)