Here's my original post: Why is data I upload getting renamed, and corresponding data added to different rows?
I was able to edit the code a little bit (using the solution I was given) so that the image that was submitted to the server via the insert form had the same name as the file I uploaded.
Example: I upload turtle.jpg into the form and click Insert. The file
"turtle.jpg" would be written into the database where it is located at
on the server (images/turtle.jpg). And then a success message would
pop up.
But everytime I sent data, the image and the other data would be inserted into the database on 2 SEPERATE rows. I have no idea why. I also tried modifying my code so that it used mysqli instead of mysql and nothing works anymore. No errors but no data is sent into the database.
Here's my new php code:
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Create connection
$conn = new mysqli('$host', '$user', '$pass', '$databasename');
// Check connection
if (mysqli_connect_error()) {
die("Database connection failed: " . mysqli_connect_error());
}
if (!empty($_FILES["uploadedimage"]["name"])) {
$file_name=$_FILES["uploadedimage"]["name"];
$temp_name=$_FILES["uploadedimage"]["tmp_name"];
$imgtype=$_FILES["uploadedimage"]["type"];
$ext= GetImageExtension($imgtype);
$imagename= $_FILES['uploadedimage']['name'];
$target_path = "images/".$imagename;
$result = $mysqli->query("INSERT INTO charts ( charts_URL ) VALUES ('".$target_path."')");
or die(mysqli_error($mysqli));
} else {
echo "<p> It is not working </p>";
}
if(isset($_POST['submit'])){ // Fetching variables of the form which travels in URL
$date = $_POST['date'];
$retrace = $_POST['retrace'];
$start_of_swing_trade = $_POST['start_of_swing_trade'];
$end_of_swing_trade = $_POST['end_of_swing_trade'];
$bull_flag = $_POST['bull_flag'];
$bear_flag = $_POST['bear_flag'];
$ema_crossover = $_POST['ema_crossover'];
$trading_instrument = $_POST['trading_instrument'];
if($date !=''||$trading_instrument !=''){
//Insert Query of SQL
$sql = "INSERT into charts (charts_date, charts_retrace, charts_start_of_swing_trade, charts_end_of_swing_trade, charts_bullflag, charts_bearflag, charts_ema_crossover, charts_trading_instrument) VALUES ('$date', '$retrace', '$start_of_swing_trade', '$end_of_swing_trade', '$bull_flag', '$bear_flag', '$ema_crossover', '$trading_instrument')";
if (mysqli_query($conn, $sql)) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
}
mysqli_close($conn); // Closing Connection with Server
The only time that data is inserted into the database is when I use the old mysql_query code. But my database says it supports the mysqli extension.
Database server
Server: Localhost via UNIX socket
Server type: MySQL
Server version: 5.5.35-cll-lve - MySQL Community Server (GPL)
Protocol version: 10
User: cpses_msLpFymSYl#localhost
Server charset: UTF-8 Unicode (utf8)
Web Server
cpsrvd 11.48.1.2
Database client version: libmysql - 5.1.73
PHP extension: mysqli Documentation
phpmyadmin
Version information: 4.0.10.7, latest stable version: 4.4.2
Here's a snippet of the my current PHP code (which is basically the code you posted in your solution) with the GetImageExtension function added:
if(isset($_POST['submit'])){
$conn = new mysqli($host, $user, $pass, $databasename);
// Check connection can be established
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
function GetImageExtension($imagetype)
{
if(empty($imagetype)) return false;
switch($imagetype)
{
case 'image/bmp': return '.bmp';
case 'image/gif': return '.gif';
case 'image/jpeg': return '.jpg';
case 'image/png': return '.png';
default: return false;
}
}
$target_path = '';
if (!empty($_FILES["uploadedimage"]["name"])) {
$file_name=$_FILES["uploadedimage"]["name"];
$temp_name=$_FILES["uploadedimage"]["tmp_name"];
$imgtype=$_FILES["uploadedimage"]["type"];
$ext= GetImageExtension($imgtype);
$imagename= $_FILES['uploadedimage']['name'];
$target_path = "images/".$imagename;
$date = $_POST['date'];
$retrace = $_POST['retrace'];
$start_of_swing_trade = $_POST['start_of_swing_trade'];
$end_of_swing_trade = $_POST['end_of_swing_trade'];
$bull_flag = $_POST['bull_flag'];
$bear_flag = $_POST['bear_flag'];
$ema_crossover = $_POST['ema_crossover'];
$trading_instrument = $_POST['trading_instrument'];
You might need to check the variable names and adjust it to your liking. Use prepared statement to prevent sql injection.
if(isset($_POST['submit'])){
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection can be established
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$target_path = '';
if (!empty($_FILES["uploadedimage"]["name"])) {
$file_name=$_FILES["uploadedimage"]["name"];
$temp_name=$_FILES["uploadedimage"]["tmp_name"];
$imgtype=$_FILES["uploadedimage"]["type"];
$ext= GetImageExtension($imgtype);
$imagename= $_FILES['uploadedimage']['name'];
$target_path = "images/".$imagename;
}
$date = $_POST['date'];
$retrace = $_POST['retrace'];
$start_of_swing_trade = $_POST['start_of_swing_trade'];
$end_of_swing_trade = $_POST['end_of_swing_trade'];
$bull_flag = $_POST['bull_flag'];
$bear_flag = $_POST['bear_flag'];
$ema_crossover = $_POST['ema_crossover'];
$trading_instrument = $_POST['trading_instrument'];
if($date !=''||$trading_instrument !=''){
$sql = "INSERT into charts (charts_URL, charts_date, charts_retrace, charts_start_of_swing_trade, charts_end_of_swing_trade, charts_bullflag, charts_bearflag, charts_ema_crossover, charts_trading_instrument) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
// s = string, i = integer, d = double, b = blob
//preparing statement
$stmt = $conn->prepare($sql);
if(!$stmt){ exit("prepare failed");}
//binding param
$bind = $stmt->bind_param('sssssssss',$target_path, $date, $retrace, $start_of_swing_trade, $end_of_swing_trade, $bull_flag, $bear_flag, $ema_crossover, $trading_instrument);
if(!$bind){ exit("bind failed");}
//will return 0 if fail
if($stmt->execute() != 0){
echo "New record created successfully";
}else{ echo "Failed to insert new record";}
}
//close connection
$conn->close();
}
But everytime I sent data, the image and the other data would be inserted into the database on 2 SEPERATE rows. I have no idea why.
Why would you expect it to land in the same row? You perform two different insert queries. If you do want to use two queries, the second one would have to be an update of the previously inserted row. But obviously, that's not the preferred way, just use one query.
Combine your if (!empty($_FILES["uploadedimage"]["name"])) and if(isset($_POST['submit'])) and then use something like this, where you insert the URL at the same time into the same row as all the other values:
INSERT into charts (charts_URL, charts_date, charts_retrace, charts_start_of_swing_trade, charts_end_of_swing_trade, charts_bullflag, charts_bearflag, charts_ema_crossover, charts_trading_instrument) VALUES (?,?,?,?,?,?,?,?)
Security
Please note that your code is extremely unsecure. $imagename is user controlled, so your first query is open to SQL injection. The values in your second query are obviously user controlled, that too is vulnerable. SQL injection can take place in all sorts of queries, including on inserts. It makes it possibly to leak data, DOS you, and possibly execute code or change data. Use prepared statements to protect against SQL injection. It's simple to use and results in nice code, there is no reason not to use it.
Note also that $_FILES["uploadedimage"]["type"] is user controlled as well and independent of the actual file type or extension. You should not trust it when deciding on the extension of the image on your server (if you do, an attacker could eg upload a PHP script).
Related
My code:
<?php
try {
$t = '040485c4-2eba-11e9-8e3c-0231844357e8';
if (array_key_exists('t', $_REQUEST)) {
$t = $_REQUEST["t"];
}
if (!isset($_COOKIE['writer'])) {
header("Location: xxx");
return 0;
}
$writer = $_COOKIE['writer'];
$dbhost = $_SERVER['RDS_HOSTNAME'];
$dbport = $_SERVER['RDS_PORT'];
$dbname = $_SERVER['RDS_DB_NAME'];
$charset = 'utf8' ;
$dsn = "mysql:host={$dbhost};port={$dbport};dbname={$dbname};charset={$charset}";
$username = $_SERVER['RDS_USERNAME'];
$password = $_SERVER['RDS_PASSWORD'];
$pdo = new PDO($dsn, $username, $password);
$stmt = $pdo->prepare("select writer from mydbtbl where writer=? and t=?");
$stmt->execute(array($writer, $t));
$num = $stmt->fetch(PDO::FETCH_NUM);
if ($num < 1) {
header("Location: login.php");
return 0;
}
$dbMsg = "Authorized";
$dbname = 'imgs';
$dsn = "mysql:host={$dbhost};port={$dbport};dbname={$dbname};charset={$charset}";
$pdo = new PDO($dsn, $username, $password);
if (isset($_FILES['filename'])) {
$name = $_FILES['filename']['name'];
// set path of uploaded file
$path = "./".basename($_FILES['filename']['name']);
// move file to current directory
move_uploaded_file($_FILES['filename']['tmp_name'], $path);
// get file contents
$data = file_get_contents($path, NULL, NULL, 0, 60000);
$stmt = $pdo->prepare("INSERT INTO file (contents, filename, t) values (?,?,?)");
$stmt->execute(array
($data,
$name,
$t)
);
$dbMsg = "Added the file to the repository";
// delete the file
unlink($path);
}
} catch (Exception $e) {
$dbMsg = "exception: " . $e->getMessage();
}
In the code you will see that the first part is for doing authentication. Then I create a new PDO object on the img schema, and do my file insert query after that.
Later, where I am printing out $dbMsg, it is saying "added file to the repository". But when I query the database (MySQL on Amazon AWS using MySQL Workbench) nothing has been inserted.
I don't understand why if nothing is getting inserted I am not getting an error message. If it says "added file to the respository", doesn't that mean the insert was successful? The only thing I can think is that using a different schema for this is mucking things up. All of my inserts to ebdb are going through fine
--- EDIT ---
This question was marked as a possible duplicate on my query about not getting an error message on my insert / execute code. This was a useful link and definitely something I will be aware of and check in the future, but ultimately the answer is the one I have provided regarding the terms of service for my aws account
The answer is that the (free) amazon account policy I am working under only allows me to have 1 database / schema. When I switched the table over to ebdb it worked right away. I am answering my own question (rather than deleting) so hopefully others using AWS / MySQL can learn from my experience.
I'm trying to execute an Insert query to write data into a Database. I'm using Mysqli and PHP.
The code looks OK for me. However, every time I go to the webpage to check if the form works, the query gets executed an a new row is created in the DB (empty).
I'm pretty sure there is something wrong with the last if statement. Could you advise?
BTW, the snippet is only for the PHP to execute the sql query, since the form is working just fine.
Thanks!
$servername = "localhost";
$username = "root";
$password = "mysqlpassword";
$dbname = "bowieDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$album = $_POST['album'];
$relyear = $_POST['relyear'];
$label = $_POST['label'];
$chart = $_POST['chart'];
$track1 = $_POST['track1'];
$track2 = $_POST['track2'];
$track3 = $_POST['track3'];
$track4 = $_POST['track4'];
$track5 = $_POST['track5'];
$sql = "INSERT INTO Albums (album, relyear, label, chart, track1, track2, track3, track4, track5)
VALUES ('$album', '$relyear', '$label', '$chart', '$track1', '$track2', '$track3', '$track4', '$track5')";
$result = mysqli_query($conn, $sql);
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
You are mixing Procedural and Object Orientated SQL interactions.
This is Procedural:
$result = mysqli_query($conn, $sql);
This is Object Orientated:
$conn->query($sql)
You can not use both with the same connection details, you should do one or the other throughout your code. The best one to use is Object Orientated approach, so rework the Procedural code to:
$result = $conn->query($sql);
if ($result) {
...
So actually you can simply remove the line starting $result = ... and let the IF statement query you already have handle itself.
Other notes:
Use MySQL error feedback such as checking if(!empty($conn->error)){print $conn->error;} after SQL statements. See example code below...
Use the following PHP error feedback too, set at the very top of your PHP page:
...
error_reporting(E_ALL);
ini_set('display_errors',0);
ini_set('log_errors',1);
you need to read up and be aware of SQL injection that can destory your database should someone POST data that also happens to be MySQL commands such as DROP.
Code for Comment:
if ($_SERVER['REQUEST_METHOD'] == "POST") {
//run SQL query you already have coded and assume
// that the form has been filled in.
$result = $conn->query($sql);
if ($result) {
//all ok
}
if(!empty($conn->error)) {
print "SQL Error: ".$conn->error;
}
}
use
1. if(isset($_POST['Submit'])){//your code here }
and
2. if($result){...
if you are using procedural method
I have been working on uploading picture to a folder and saving the file name and some meta info to a MySQL database. I got everything working on PHP but nothing changes on my database. I don't know what is wrong.
<?php
$servername = "localhost";
$username = "root";
$password = "pass";
$dbname = "poster";
$uploadOk = "0";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
if (isset($_POST['btn-upload'])) {
$owner = $_POST['userid'];
$file = rand(1000,100000)."-".$_FILES['file']['name'];
$file_loc = $_FILES['file']['tmp_name'];
$file_size = $_FILES['file']['size'];
$file_type = $_FILES['file']['type'];
$folder = "profile/";
if (!empty ($owner)) {
$uploadOk = 1;
} else {
echo "Are you sure you are not in the wrong place?";
$uploadOk = 0;
}
$new_size = $file_size/1024;
// new file size in KB
// make file name in lower case
$new_file_name = strtolower($file);
// make file name in lower case
$final_file=str_replace(' ','-',$new_file_name);
if ($file_type != 'jpg' ) {
$uploadOk = 1;
} else {
echo "Only jpg file type allowed.";
$uploadOk = 0;
}
}
if ($file_size > '5000') {
$uploadOk = 1;
} else {
echo "Your image file must be less than 5Mb";
$uploadOK = 0;
}
if (move_uploaded_file($file_loc,$folder.$final_file) && $uploadOk == 1) {
$sql = "UPDATE post SET `file`='$final_file', `type` = '$file_type' WHERE `userid`='$owner'";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . $conn->error;
}
}
$conn->close();
?>
Html Result
Record updated successfully
Database
|userid | file|type|
| 1 | foo | foo|
It said record updated successfully but nothing gets updated in my database. What did I do wrong here?
p.s.
Yes I do know that I should be using PDO by now, but I just need to finish this as my first PHP project.
Thank you in advance.
You are jumping between procedural style and object oriented style with your queries; this may be part of your problem.
Try changing your connection to this:
$conn = new mysqli($servername, $username, $password, $dbname);
Incidentally, since you mention it, you don't necessarily have to use PDO for prepared statements. As you like mysqli, you can do it with these. You are already halfway there. After you've done the above, just do this:
$sql = $conn->prepare("UPDATE post SET `file`= ?, `type` = ? WHERE userid= ? ");
$sql->bind_param("ssi", $file, $file_type, $owner);
$sql->execute();
$sql->close();
The ssi above just refers to "string string integer" (or whatever file types you are using, assuming the first two are varchars, and the third is an INT). Basically you are setting the parameters for each file to go into your query; you don't need to remember whether to quote or not quote the variable depending on type, as you've defined it in the bind_param() below.
It's fairly self-explanatory, and not hard to learn. Like I said, you are halfway there.
I think you have just made a error in either you database design or the way you record the new upload.
UPDATE post SET `file`='$final_file', `type` = '$file_type' WHERE `userid`='$owner'";
This will amend an already created row. So you will only ever have one row per user, and therefore when the user uploads a second file it will over write the previous data.
Assuming the userid column is not defines as auto increment you should in fact be creating a new row for each file a user uploads with an INSERT query rather than an UPDATE like so
INSERT INTO post (userid,file,type)
VALUES ('$owner', '$final_file', '$file_type')
Now you will get a new row for this user for each file they upload.
I have a form that uploads a file with other information to a database and displays it in a chart. Right now the chart only displays the file name and doesen't link it. If the file was called test1.pdf, how would I make it so on the chart it still says chart1.pdf but links it to the directory that the file is on?
if ('POST' === $_SERVER['REQUEST_METHOD'])
{
$con = mysql_connect("localhost","xxxx","xxxxx");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("jjlliinn_test", $con);
$target = "clientdoc/";
$target = $target . basename( $_FILES['file']['name']);
$date = $_POST['date'];
$propertydescription = $_POST['propertydescription'];
$transactiontype = $_POST['transactiontype'];
$applicabledocument = ($_FILES['file']['name']);
$received = $_POST['received'];
$paid = $_POST['paid'];
//Writes the to the server
if(move_uploaded_file($_FILES['file']['tmp_name'], $target))
{
//Tells you if its all ok
echo "";
}
else {
//Gives and error if its not
echo "Sorry, there was a problem uploading your file.";
}
$sql = mysql_query("INSERT INTO `transactions` (`date`, `agentclient`, `propertydescription`, `transactiontype`, `applicabledocument`, `received`, `paid`)
VALUES
('$date', '$agentclient', '$propertydescription', '$transactiontype', '$applicabledocument', '$received', '$paid')") or die(mysql_error());
$query = mysql_query($sql);
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
echo "Succesfully added transaction. Updating table...";
echo "<META HTTP-EQUIV=\"refresh\" CONTENT=\"48\">";
mysql_close($con);
}
}
?>
Assuming all your uploads are stored in the client doc folder and you have run the query to get the recordset from the transactions table...
link text
Another point, looking at the code, sending raw $_POST values direct to the db is asking for sql injection trouble. Have a look at either htmlentities with ENT_QUOTES set or the input filters available with php.
I am using this code to insert some values in MySql table:
<?php
mysql_connect("localhost","root","root");
mysql_select_db("bib");
$id = "12";
$titlu = "Joe";
$query = "INSERT INTO carte SET id='$id', titlu='$titlu'";
$result = mysql_query($query);
// Display an appropriate message
if ($result)
echo "<p>Product successfully inserted!</p>";
else
echo "<p>There was a problem inserting the Book!</p>";
mysql_close();
?>
After running it into browser, the following error occurs:
"Apache HTTP Server has encountered a problem and needs to close. We are sorry for the inconvenience."
It seems that mysql_select_db("bib") statement causes it. Database is create , also table...
I am running php 5.3 and mysql 5.1 on windows xp sp 2.
Please any ideas are welcomed...
Thanks...
Any of the mysql_* functions can fail for various reasons. You have to check the return values and if a function indicates an error (usually by returning FALSE) your script has to react appropriately.
mysql_error($link) and mysql_errno($link) can give you more detailed information about the cause. But you don't want to show all the details to just any arbitrary user, see CWE-209: Information Exposure Through an Error Message.
If you don't pass the connection resource returned by mysql_connect() to subsequent mysql_* functions calls, php assumes the last successfully established connection. You shouldn't rely on that; better pass the link resource to the functions. a) If you ever have more than one connection per page you must pass it anyway. b) If there is no valid db connection the php-mysql modules tries to establish the default connection which is usually not what you want; it only takes up more time to fail ..again.
<?php
define('DEBUGOUTPUT', 1);
$mysql = mysql_connect("localhost","root","root");
if ( !$mysql ) {
foo('query failed', mysql_error());
}
$rc = mysql_select_db("bib", $mysql);
if ( !$rc) {
foo('select db', mysql_error($mysql));
}
$id = "12";
$titlu = "Joe";
$query = "INSERT INTO carte SET id='$id', titlu='$titlu'";
$result = mysql_query($query, $mysql);
// Display an appropriate message
if ($result) {
echo "<p>Product successfully inserted!</p>";
}
else {
foo("There was a problem inserting the Book!", mysql_error($mysql), false);
}
mysql_close($mysql);
function foo($description, $detail, $die=false) {
echo '<pre>', htmlspecialchars($description), "</pre>\n";
if ( defined('DEBUGOUTPUT') && DEBUGOUTPUT ) {
echo '<pre>', htmlspecialchars($detail), "</pre>\n";
}
if ( $die ) {
die;
}
}
try this to connect to database:
$mysqlID = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD) or die("Unable to connect to database");
mysql_select_db(DB_DATABASE) or die("Unable to select database ".DB_DATABASE);
also, try this as your insert query:
$query = "INSERT INTO carte (id, title) values ('".$id."', '".addslashes($titlu)."')
$result = mysql_query($query) or die(mysql_error());
By using die(), it will tell you where it has failed and why