Storing into the database - Issue - php

I am currently working on an image upload script however I am running into a slight issue when trying to store details of the image into the database.
The upload form grabs the image, checks its details and gets the extension of the image. This works fine however it won't store the image path into the database.
This is the part of the code in question:
$file_path = 'images/profile/' . substr(md5(time()), 0, 10) . '.' . $file_extn;
echo $file_path;
try {
$con = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "UPDATE user SET img=$file_path WHERE userID = $username";
$stmt = $con->prepare( $sql );
$stmt->bindValue( "file_path", $this->file_path, PDO::PARAM_STR );
$stmt->execute();
if ( $stmt->rowCount() > 0 ) {
echo ('Complete');
}
else {
echo ('Error');
}
}catch( PDOException $e ) {
return $e->getMessage();
}
}
Now the reason I have "echo $file_path;" there was to make sure the values were passing correctly, which they are.
It currently echo's this out if an image is uploaded: images/profile/f1b4edb293.jpg
So everything is working fine, it just failes at the point of actually storing.
Now to further test I even remove the string and path details from the file_path variable and just added a dummy value in there e.g:
$test = "test";
$file_path = $test;
And sure enough, it worked and inserted test into the database.
So that leads me to believe there is an issue with the format of this:
$file_path = 'images/profile/' . substr(md5(time()), 0, 10) . '.' . $file_extn;
Any ideas on what part of that is stopping it from saving to the database?

You are injecting PHP strings into your SQL code, thus generating unquoted SQL strings (and opening your script to SQL injection):
$file_path = 'images/profile/' . substr(md5(time()), 0, 10) . '.' . $file_extn;
$sql = "UPDATE user SET img=$file_path WHERE userID = $username";
If you var_dump($sql), you'll see that you are generating invalid SQL. (I wonder why no exception is being thrown.)
However, we see this later:
$stmt->bindValue( "file_path", $this->file_path, PDO::PARAM_STR );
So I guess you are aware of prepared statements but you confusing the place-holder syntax (either :file_path or ?) with PHP's string interpolation ($file_path). Again, you should be getting an exception because you're binding a non-existent parameter :-?
Additionally, you have both $file_path and $this->file_path. One of them is probably a typo.
You need to replace this:
$sql = "UPDATE user SET img=$file_path WHERE userID = $username";
$stmt = $con->prepare( $sql );
$stmt->bindValue( "file_path", $this->file_path, PDO::PARAM_STR );
... with this:
$sql = "UPDATE user SET img=:file_path WHERE userID = :username";
$stmt = $con->prepare( $sql );
$stmt->bindValue("file_path", $file_path, PDO::PARAM_STR );
$stmt->bindValue("username", $username, PDO::PARAM_STR );

use this code
$sql = "UPDATE user SET img=:file_path WHERE userID = :username";
$stmt = $con->prepare( $sql );
$stmt->bindValue( ":file_path", $file_path, PDO::PARAM_STR );
$stmt->bindValue( ":username", $username, PDO::PARAM_STR );
$stmt->execute();

do you not need to have file path like '$newfile' i.e.
$sql = "UPDATE user SET img='$file_path' WHERE userID = '$username'";
It's worth a try ?

Related

Unable to alter SQL using PDO statement

if (isset($_GET['ResetPassword'])) {
$name = $_GET['name'];
$sql = "ALTER LOGIN $name WITH PASSWORD=N'Nico1234!'";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':name', $_GET['name'], PDO::PARAM_STR);
$stmt->execute();
}
Hi guys I cant alter the password of a certain name(user) Where the name is from get (Selected from the sql).
Thanks for the help.
ALTER TABLE Statements are used for changing the schema of a Table like adding a Column or FOREIGN KEYS.
Are you trying to make an UPDATE Statement? The right query would be:
"UPDATE Login SET PASSWORD='Nico1234!' WHERE name=:name"
If you want to add the $_GET['name'] Parameter to the statement, you have to use :name anywhere inside it.
If you want to change the properties of a SQL Server login account, use ALTER LOGIN.
The problem here will be the parameter in your statement.
Table and column names cannot be replaced by parameters in PDO. I'm not sure, but I think that it's the same for login names.
So, in this case, you should use statement without parameters, escape special characters and sanitize the data manually.
As a note, when you want to use a parameter, the correct syntax for a placeholder is :name or ?, not $name.
<?php
...
try {
# SQL Authentication
$conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
# Windows Authentication
#$conn = new PDO("sqlsrv:server=$server;Database=$database");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
die( "Error connecting to SQL Server".$e->getMessage());
}
...
try {
$name = $_GET['name'];
$password = 'Nico1234!';
# Escape special characters and do some check for $name and $password values
$stmt = $conn->prepare("ALTER LOGIN $name WITH PASSWORD = N'$password'");
$stmt->execute();
} catch( PDOException $e ) {
die("Error executing query: ".$e->getMessage() );
}
...
?>
ALTER LOGIN needs permissions to execute correctly. If you use Windows authentication, then the Web server's process identity or thread identity (if the Web server is using impersonation) is used to connect to the SQL Server. Use next script for more information (change between SQL and Window authentication):
<?php
# Connection
$server = 'server\instance,port';
$database = 'database';
$uid = 'uid';
$pwd = 'pwd';
# PDO Connection
try {
# SQL authentication
#$conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
# Windows authentication
$conn = new PDO("sqlsrv:server=$server;Database=$database");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
die( "Error connecting to SQL Server".$e->getMessage());
}
#
try {
$stmt = $conn->query("SELECT 'SUSER_SNAME' AS [NAME], CONVERT(nvarchar(128), SUSER_SNAME()) AS [VALUE]");
# Data
while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ){
echo $row['NAME'].": ".$row['VALUE']."</br>";
}
} catch( PDOException $e ) {
die( "Error executing query".$e->getMessage() );
}
#
$stmt = null;
$conn = null;
?>

How do I store and retrieve a colon (:) in a MySQL field?

I'm simply trying to store a URI in a MySQL table. When I retrieve it the ":" disappears. So http://www.example.com becomes http//www.example.com I've researched it and there are solutions for ; (semicolons), , (commas), quote marks et etc., but not for colons.
I've tried http \ ://www.xyz.com (no spaces) but that converts it http/://www.example.com I'm using php. Any suggestions?
Here is the code:
<?php
$id = $_GET["id"];
$conn = new mysqli($servername, $username, $password, $dbname); //security parameters not shown
$sql = "SELECT * FROM uri WHERE myURI='" . $id . "'";
$result = $conn->query($sql);
if ($result) {
$row = $result->fetch_assoc();
if ($row) {
$SendTo = $row["SendTo"];
header("Location: " . $SendTo);
}
}
?>
Note: I am not showing insertion code because at this stage I am simply entering the URI manually to create a POC.
Use mysqli_real_escape_string() function to escape slashes and store safely in database
For e.g.
$url = "http://www.example.com";
$safeURL = mysqli_real_escape_string($url);
and then use $safeURL var in SQL to store.

Scanning with scanimage from php from a linux host

Here's what the situation is: I am trying to use PHP to call scanimage on a Linux host, then save the resulting file to a web directory for future use.
The below code produces no errors, but when I check out the /tmp directory, file.pnm is blank, and the scanner never starts.
<?php
require('/var/www/olin/includes/functions.php');
$con = connect_db();
//setup the POST variables
if (isset($_POST['submit'])) {
$fname = mysqli_real_escape_string($con, $_POST['fname']);
$lname = mysqli_real_escape_string($con, $_POST['lname']);
$license_no = mysqli_real_escape_string($con, $_POST['license_no']);
$comments = mysqli_real_escape_string($con, $_POST['comments']);
}
if ($license_no == '') {
$license_no = "None on File";
}
if ($fname == '' || $lname == '') {
echo '<h1 class="message">Can\'t submit visitor: you are missing information!</h1>';
} else {
//setup the query and prepare it for exection
$query= "insert into visitors (fname, lname, license_no, redsheet, comments)" .
" values (?, ?, ?, 'Allow', ?) on duplicate key update fname = values(fname)," .
"lname = values(lname), license_no = values(license_no), redsheet = values(redsheet)," .
"comments = values(comments)";
$stmnt= mysqli_prepare($con, $query);
//bind the statement parameters to variables
mysqli_stmt_bind_param($stmnt, "ssss", $fname, $lname, $license_no, $comments );
//execute, then close the statment
if (!mysqli_stmt_execute($stmnt)) {
echo "Failed to ececute the query: " . mysqli_error($con);
header('Refresh: 10; url=http://localhost/olin/visitor.php');
}
}
// we'll `try` to scan the license if the checkbox is selected
if (isset($_POST['pic_id'])) {
// get the info from the db
$query = 'select id from visitors where license_no = "'.$license_no.'"';
$result = mysqli_query($con, $query);
while ($row = mysqli_fetch_array($result)) {
$id = $row['id'];
// set up the path to save the id to (and put path into db for further look up
// and display)
$dir = ( $id % 30 );
$path = '/var/www/olin/images/licenses/'.$dir.'/'.$id.'-license.png';
$path = addslashes(mysqli_real_escape_string($con, $path));
$path1 = '/images/licenses/'.$dir.'/'.$id.'-license.png';
// start the scan, and save image
$command = '/home/jmd9qs/bin/scan.sh "'.$path.'"';
$update = 'update visitors set id_pic = "'.$path1.'" where id="'.$id.'"';
mysqli_query($con, $update) or die ('Error: ' . mysqli_error($con));
exec($command);
header('Location: http://localhost/olin/visitor.php');
}
}
?>
Can anybody provide any hints?
UPDATE:
I have the server running the command now (I know it's failing because of the Apache2 error log).
Here's the error I get:
scanimage: open of device brother3:bus2;dev1 failed: Invalid argument
I've tried adding the www-data user to the scanner and lp groups, but it seems to have no effect... The scanimage command I'm using works under my normal user and as root, so I'm now positive the command I'm using should work. I am still at a loss...
UPDATE (again):
I've fixed some errors in my code... now the server will scan and successfully save images! However, it only works once and then for some odd reason I have to run the scan.sh (which I put the scanimage command into) through my shell for it to run again... otherwise I get the same error message!
Very weird, I have NO clue why, suggestions wanted!

PHP PDO not executing SQL command

I'm working on a PHP script to reset a user's password. I have an email and a token check setup so that those two must be valid before the user is allowed to reset. So far, everything works up to the point where I insert the password into the database. Here's the code for my PDO (I broke the SQL query at those parts so it's easier to glance over):
try {
$sql = "UPDATE users
SET password=:password, sessionTime=:sessionTime, sessionID=:sessionID
WHERE sessionID=:sessionID";
$update = $con->prepare($sql);
$update->bindValue("password", hash("sha256", $password . $salt), PDO::PARAM_STR);
$update->bindValue("sessionID", "0", PDO::PARAM_STR );
$update->bindValue("sessionTime", "0", PDO::PARAM_STR );
$update->execute();
echo "<br /> Successfully updated the password!";
} catch(PDOException $e) {
throw new Exception('something went wrong with the password reset', 0, $e);
}
$salt and $password are defined prior to this, and when I run the script, it outputs Successfully updated the password!, however, nothing changes in my database. When I copy and paste the query into phpMyAdmin and change the :name parameters to actual strings, it works perfectly (updating my database) and doesn't return any errors - also, I'm not getting anything in php_error.log, so I'm not really sure why this isn't working.
Any help would be appreciated, thank you.
Can you run the script with errorInfo like below and report the results:
<?php
try {
$sql = "UPDATE users
SET password=:password, sessionTime=:sessionTime, sessionID=:sessionID
WHERE sessionID=:sessionID";
$update = $con->prepare($sql);
$update->bindValue("password", hash("sha256", $password . $salt), PDO::PARAM_STR);
$update->bindValue("sessionID", "0", PDO::PARAM_STR );
$update->bindValue("sessionTime", "0", PDO::PARAM_STR );
$update->execute();
var_dump($update->errorInfo());
echo "<br /> Successfully updated the password!";
} catch(PDOException $e) {
throw new Exception('something went wrong with the password reset', 0, $e);
}

Can I convert mysql functions to PDO one at a time?

I have a bunch of mysql queries in my sight that Im going to need to convert to PDO. Can I do this one query at a time and all other functions continue to work? For example if I convert 1 query to PDO with that hinder all my other mysql queries from working properly?
That should work without any problems as long as you have 2 database connections open, one for the mysql_* functions and one for PDO.
The only potential drawback is the temporary extra overhead of the two db connections instead of one.
I don't see why it would, unless you're using some sort of special database handler class or something.
One thing you might want to consider is not using a "connections" script, but using more of an OOP/data-model setup.
Basically, you keep your connection details in a separate file - mine just defined some constants that I could access later in the script in which it gets included. From there, you create a class that is responsible for establishing it's own connection when instantiated. This class will contain methods that correspond to your typical queries, with maybe a method to run a raw query as needed.
The advantage of doing this is that you can basically leave your existing code alone, and just add your new data model code where you want, as you update or replace your existing scripts.
For reference's sake, here's a stripped down version of code I used to use:
db.php
<?php
# Set the database access information as constants.
DEFINE ('DB_USER', 'your_db_user_name');
DEFINE ('DB_PASSWORD', 'your-super-duper-secret-password');
DEFINE ('DB_HOST', 'localhost');
DEFINE ('DB_NAME', 'schema-name');
DEFINE ('DB_CONNECTION', 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME );
?>
blog-model.php
<?php
# File: blog-model.php
# Version: 1.0
# Updated: 2011.9.4
# Meta: This file contains the database access information.
# This file also establishes a connection to MySQL and selects the database.
#require_once( ROOT . DS . 'config' . DS . 'db.php' );
# Utility Class
class BlogModel {
protected $pdo;
# Constructor
function __construct() {
$this->connect();
}
function __destruct() {
}
# Connect to the database
function connect() {
# Database connectivity can be a tricky beast, so I'm wrapping the entire block in a try/catch
try {
$this->pdo = new PDO( DB_CONNECTION, DB_USER, DB_PASSWORD, array( PDO::ATTR_PERSISTENT => true ) );
# Set character set to UTF-8 (adds support for non-ASCII languages).
# Note this can cause issues with BLOB-style fields, especially with INSERTs
$this->pdo->exec( "SET CHARACTER SET utf8" );
return true;
}
catch(PDOException $e) {
# Add code to write out error log and alert administrator
trigger_error( "<p>Could not select the database</p>\n<p>MySQL Error: " . $e->getMessage() . "</p>" );
return false;
}
}
# Run an INSERT query; that is, insert a new row (or rows) into a MySQL table
function insert( $authorid, $title, $permalink, $category, $body, $tags, $abstract ) {
try {
# Named parameters (prefered)
$stmt = $this->pdo->prepare(
"INSERT INTO pages
SET title = :title,
permalink = :permalink,
category = :category,
body = :body,
tags = :tags,
abstract = :abstract,
author = :authorid,
timestamp = NOW();"
);
$stmt->bindParam( ':title', $title );
$stmt->bindParam( ':permalink', $permalink );
$stmt->bindParam( ':category', $category );
$stmt->bindParam( ':body', $body );
$stmt->bindParam( ':tags', $tags );
$stmt->bindParam( ':abstract', $abstract );
$stmt->bindParam( ':authorid', $authorid, PDO::PARAM_INT );
return $stmt->execute();
}
catch( Exception $e ) {
# Add code to write out error log and email administrator
trigger_error( "<p>An error occurred whilst executing your query:\n<br />MySQL Error: " . $e->getMessage() . "</p>" );
return false;
}
}
# Run an UPDATE query; that is, update an existing row (or rows) in a MySQL table
function update( $id, $title, $category, $body, $tags, $abstract ) {
try {
# Update the project matching the supplied id
# Named parameters (prefered)
$stmt = $this->pdo->prepare(
"UPDATE pages
SET title = :title, category = :category, body = :body, tags = :tags, abstract = :abstract, lastupdated = NOW()
WHERE permalink = :id
LIMIT 1;"
);
$stmt->bindParam( ':id', $id );
$stmt->bindParam( ':title', $title );
$stmt->bindParam( ':category', $category );
$stmt->bindParam( ':body', $body );
$stmt->bindParam( ':tags', $tags );
$stmt->bindParam( ':abstract', $abstract );
return $stmt->execute();
}
catch( Exception $e ) {
# Add code to write out error log and email administrator
trigger_error( "<p>An error occurred whilst executing your query:\n<br />MySQL Error: " . $e->getMessage() . "</p>" );
return false;
}
}
# Run a DELETE query; that is, remove a record (or records) from a MySQL table
function delete( $id ) {
try {
# Delete the project matching the supplied id
# Named parameters (prefered)
$stmt = $this->pdo->prepare( "DELETE FROM pages WHERE id = :id LIMIT 1;" );
$stmt->bindParam( ':id', $id, PDO::PARAM_INT );
return $stmt->execute();
}
catch( Exception $e ) {
# Add code to write out error log and email administrator
trigger_error( "<p>An error occurred whilst executing your query:\n<br />MySQL Error: " . $e->getMessage() . "</p>" );
return false;
}
}
# Close the connection
function close() {
$this->pdo = null;
}
}
?>
This is all probably not entirely relevant to your original question, but maybe you (or some random Google-er) can derive some use from it.

Categories