This is an extension of a question I asked a wee while ago which #eHussain was nice enough to help out with.
I have form which inserts various details into a MySQL table and uploads a file (the name of which is also registered in the database). This works fine. The issue comes when I update, say, the name and not the image. In this case the image name is over written as 'blank', and rightly so as that's the value in the file field.
The update code:
<?php
error_reporting(E_ALL^E_NOTICE);
define('INCLUDE_CHECK',true);
include "connect.php";
$target = "../uploads/";
$target = $target . basename( $_FILES['photo']['name']);
//This gets all the other information from the form
$name=$_POST['name'];
$url=$_POST['url'];
$description=$_POST['description'];
$pic=($_FILES['photo']['name']);
$author=$_POST['author'];
$company=$_POST['company'];
$published=$_POST['published'];
$dashboardID=$_POST['dashboardID'];
//Writes the information to the database
mysql_query("UPDATE dashboard SET name='$name', url='$url', description='$description', documentName='$pic', author='$author', company='$company', publish='$published' WHERE dashboardID='$dashboardID'");
//Writes the photo to the server
if(isset($_FILES['photo']['tmp_name'])) // check if any file is uploaded
{
if(move_uploaded_file($_FILES['photo']['tmp_name'], $target))
{
header("Location: ../dashboard.php?success=2"); } else {
header("Location: ../dashboard.php?success=0"); }
}
?>
I understand the 'isset' to avoid a the error generated if no file is selected, but I don't understand how I can extent this to avoid updating a field which has a blank value.
Do a check on the $_FILES array before running the query.
From there, you can either dynamically build the query (including or excluding the documentName field) or alternatively, fetch the current value and assign it to $pic.
For example (untested)
$values = array(
'name' => $name,
'url' => $url,
// etc
);
if (isset($_FILES['photo']['name'])) {
$values['documentName'] = $_FILES['photo']['name']
}
// mysql functions are naff, use PDO
$query = 'UPDATE dashboard SET %s WHERE dashboardID = :dashboardID';
$set = array();
foreach (array_keys($values) as $col) {
$set[] = sprintf('`%s` = :%s', $col, $col);
}
$stmt = $pdo->prepare(sprintf($query, implode(', ', $set)));
$values['dashboardID'] = $dashboardID;
$stmt->execute($values);
#rrfive , please try below method, hope it will work,
//first put all post variable in an array
$post_data = compact($_POST);
$pic=($_FILES['photo']['name']);
//now push pic name in `$post_data`
if (!empty($pic) ) { array_push( $post_data,$pic ) }
//now use UPDATE query using `vsprintf` . but first check the order of `$post_data` #Thanks Phill
$stmt = "UPDATE dashboard SET
name='%s',
url='%s',
description='%s',
author='%s',
company='%s',
publish='%s'";
$stmt .=(!empty($pic)) ? documentName='%s', : "";
$stmt .= "WHERE dashboardID=%d";
// To check the complete query before execute. uncomment below 2 lines
//print vsprintf($stmt,$post_data);
//die;
mysql_query( vsprintf($stmt,$post_data) );
Reference
- compact
- vsprintf
The following code should do the trick.
if(isset($_FILES)){
...stuff...
}
Related
In my local server this script works fine. When I upload this script on live it does not work properly.
It inserts only 126 rows of data into the database, but I need to upload at least 500 rows at a time.
<?php
include 'database-config.php';
foreach($_POST['classroll'] as $row=>$classroll)
{
$sclassroll = $classroll;
$mark = $_POST['mark'][$row];
$type = $_POST['rtype'];
$session = $_POST['rsession'];
$department = $_POST['rdepartment'];
$examtype = $_POST['rextype'];
$examyear = $_POST['rexyear'];
$examsubject = $_POST['rexmarksubject'];
$stmt = $dbh->prepare("INSERT INTO exammarks(studnettype, studentsession, studentdepartment, studentclassroll, examtype, examyear, examsubjec, exammarks) VALUES (:studnettype, :studentsession, :studentdepartment, :studentclassroll, :examtype, :examyear, :examsubjec, :exammarks)");
$stmt->bindParam('studnettype', $type);
$stmt->bindParam('studentsession', $session);
$stmt->bindParam('studentdepartment', $department);
$stmt->bindParam('studentclassroll', $sclassroll);
$stmt->bindParam('examtype', $examtype);
$stmt->bindParam('examyear', $examyear);
$stmt->bindParam('examsubjec', $examsubject);
$stmt->bindParam('exammarks', $mark);
$stmt->execute();
}
header('Location: ../home.php');
?>
It is possible that your exammarks table definition on your live server contains a unique index that is not present on your local host server. If that were true some of your INSERT operations might fail.
The code you showed us doesn't check for errors. Obviously, when your program deals with high value data (such as the results of student examinations) you should check for errors.
Try this instead:
if( !$stmt->execute()) {
print_r( $arr = $stmt->errorInfo() );
}
else {
/* INSERT statement completed correctly */
}
So I'm using http://www.verot.net/php_class_upload_docs.htm?lang=en-GB to upload files to a mysql database. I'm a little new at mysql so please forgive my ignorance.
the below code snippet uploads the image, renames it properly, but stores the old file name in the database table.
include('class.upload.php');
$t = time();
$foo = new Upload($_FILES['receipt_u']);
if ($foo->uploaded) {
$foo->file_new_name_body = "img_$t";
$foo->file_max_size = '4194304'; //4MB
$foo->Process('pics');
}
$receipt_img =($_FILES['receipt_u']['name']);
$sql = "INSERT INTO product (receipt_u) VALUES (:rcpt)";
$q = $conn->prepare($sql);
$q->execute(array(':rcpt'=>$receipt_img));
header("location: ../index.php");
There's actually a lot of data be passed into the database but I removed it for this purpose as this is the only thing giving me trouble.
Why is it posting the original file name into the database and not the new one?
Simple:
echo $foo->file_dst_name;
your new code looks like:
$t = time();
$foo = new Upload($_FILES['receipt_u']);
if ($foo->uploaded) {
$foo->file_new_name_body = "img_$t";
$foo->file_max_size = '4194304'; //4MB
$foo->Process('pics');
}
//here its recipt image new
$receipt_img = $foo->file_dst_name;
$sql = "INSERT INTO product (receipt_u) VALUES (:rcpt)";
$q = $conn->prepare($sql);
$q->execute(array(':rcpt'=>$receipt_img));
header("location: ../index.php");
I have a download button and when i click on it, instead of saving to disk it opens it in the browser. I tried a bunch of attempts to make it open in the browser but it doesnt seem to do anything
<?php
// make a connection to the database
require_once("connection/connection.php");
//retrieve the ID from the url to fetch the specific details
if ($_GET['id'] != ""){
$item_id = $_GET['id'];
$bad_id = FALSE;
}
else{
$item_id = "";
$bad_id = TRUE;
}
//select the specific item from the database
// run if statement to ensure valid id was passed
if (is_numeric ($_GET['id'])){
$query = "SELECT name FROM repository WHERE item_id = '$item_id'";
$result = mysql_query($query) or die(mysql_error());
// assign the values to an array
$row = mysql_fetch_assoc($result);
//assign the values from the array to variables
$name = $row['name'];
}
// define path to the xml file
$file = "xml/".$hud_name . "_cfg.xml";
// check to make sure the file exists
if(!file_exists($file)){
die('Error: File not found.');
} else{
// Set headers
header("Content-Type: application/xml");
header("Content-Disposition:attachment; filename=".basename($file)."");
readfile($file);
}
?>
That is download.php and it obviously finds the file because it doesnt give the error about it not existing. It also echos back the correct file path
Then on another page i have:
<img src="images/download.png" alt=""/>
Any ideas whats wrong?
Well the solution turned out to be simple in the end but i didnt see any documentation saying the header must be the very first line. If i placed:
header("Content-Type: application/xml");
as the first line and then the coding below it and the other header info at the end it works. Im not sure if that's the solution or a workaround but it fixed it for me
look at this code
<?
require_once("conn.php");
require_once("includes.php");
require_once("access.php");
if(isset($_POST[s1]))
{
//manage files
if(!empty($_FILES[images]))
{
while(list($key,$value) = each($_FILES[images][name]))
{
if(!empty($value))
{
$NewImageName = $t."_".$value;
copy($_FILES[images][tmp_name][$key], "images/".$NewImageName);
$MyImages[] = $NewImageName;
}
}
if(!empty($MyImages))
{
$ImageStr = implode("|", $MyImages);
}
}
$q1 = "insert into class_catalog set
MemberID = '$_SESSION[MemberID]',
CategoryID = '$_POST[CategoryID]',
Description = '$_POST[Description]',
images = '$ImageStr',
DatePosted = '$t',
DateExp = '$_SESSION[AccountExpDate]',
FeaturedStatus = '$_POST[sp]' ";
//echo $q1;
mysql_query($q1) or die(mysql_error());
}
//get the posted offers
$q1 = "select count(*) from class_catalog where MemberID = '$_SESSION[MemberID]' ";
$r1 = mysql_query($q1) or die(mysql_error());
$a1 = mysql_fetch_array($r1);
header("location:AddAsset.php");
exit();
?>
The mySql insert function isn't adding anything also it return success to me , I've tried using INSERT ... Values but what it done was overwtiting existing value ( i.e make 1 entry and overwties it everytime).
I am using PHP 4.4.9 and MySql 4
I tried to add from Phpmyadmin and it is working also it was working after installation but after i quit the browser and made a new account to test it it is not working but the old ones is working ! you can see it here http://bemidjiclassifieds.com/
try to login with usr:openbook pass:mohamed24 and you can see it will be working but any new account won't work!
Maybe $_POST[s1] is not set or you are inserting into a different database than you are watching.
if(isset($_POST[s1]))
should probably be
if(isset($_POST['s1']))
(note the quotes). Also, it's best to NOT depend on a field being present in the submitted data to check if you're doing a POSt. the 100% reliable method is
if ($_SERVER['REQUEST_METHOD'] == 'POST') { ... }
As well, you're not checking if the file uploads succeeded. Each file should be checked like this:
foreach($_FILES['images']['name'] as $key => $name) {
if ($_FILES['images']['error'][$key] !== UPLOAD_ERR_OK) {
echo "File #$key failed to upload, error code {$_FILES['images']['error'][$key]}";
}
...
}
Don't use copy() to move uploaded files. There's a move_uploaded_files() function for that, which does some extra sanity checking to make sure nothing's tampered with the file between the time the upload finished and your script tries to move it.
I've written a method to set a header() to the appropriate file type of an upload stored in a database and then I would like to echo() the file.
The method is as follows inside a controller:
function view_upload( $id = 0 ) {
$id = $this->db->escape( $id );
$query = $this->db->query( "SELECT file_type FROM media WHERE id = $id" )->row();
$query2 = $this->db->query( "SELECT file FROM media WHERE id = $id" )->row();
header("Content-type: ".$query->file_type);
//die( "moo" );
echo( $query2->file );
}
Strangely as soon as I set the header() the rest of the method seems to be ignored, for example, if I uncomment the die() statement it doesn't die and it doesn't echo the image. If I remove the header() call I see the raw upload blob presented to the screen..
Is this something to do with CodeIgniter or have I made a PHP mistake?
EDIT:
I've changed the function and put it in a separate file outside of CodeIgniter but if I browse to it and pass in an $id it still doesn't display the image...
<?php
// just so we know it is broken
error_reporting(E_ALL);
// some basic sanity checks
if(isset($_GET['id']) && is_numeric($_GET['id'])) {
//connect to the db
$link = mysql_connect("localhost", "user", "pass") or die("Could not connect: " . mysql_error());
// select our database
mysql_select_db("database") or die(mysql_error());
$id = $_GET['id'];
// get the file from the db
$sql = "SELECT file FROM media WHERE id=$id";
// the result of the query
$result = mysql_query("$sql") or die("Invalid query: " . mysql_error());
// get the file_type from the db
$sql = "SELECT file_type FROM media WHERE id=$id";
// the result of the query
$result2 = mysql_query("$sql") or die("Invalid query: " . mysql_error());
// set the header for the image
//ob_clean();
//die( mysql_result($result, 0) );
//header('Content-type:'.mysql_result($result2, 0));
header('Content-type: image/png');
//ob_clean();
echo mysql_result($result, 0);
// close the db link
mysql_close($link);
}
else {
echo 'Please use a real id number';
}
?>
die() on the two $result produces what I would expect but it's not displaying the page in the browser. Again if I add ob_clean() it says:
ob_clean() [<a href='ref.outcontrol'>ref.outcontrol</a>]: failed to delete buffer. No buffer to delete.
I've copied the code from here: http://www.phpriot.com/articles/images-in-mysql/8 if that helps at all..
It turns out that the image in the database was corrupt, and hence not displaying, because I had added addslashes() to the file contents (not really sure why, seem to remember reading it was useful in combating XSS vulnerabilities).
Removing that meant I had non-corrupt images stored and then they displayed okay.
First You need to start ob_start() just before on_clean() then you need to write like header().
Here is the follow.
ob_start();
ob_clean();
header ("Content-type: image/png");
?>
Try this let me know is this working or not hopefully it will help you.