October 29th, 2013, 07:07 PM
-
New to php ,need help understanding this php code
I found this code online and i want to understand it, i have read the php documentation but i have found out that the community in devshed offers better explanations
PHP Code:
function mysql_safe_query($query) {
$args = array_slice(func_get_args(),1);
$args = array_map('mysql_safe_string',$args);
return mysql_query(vsprintf($query,$args));
}
I figure the function isn't a builtin php function.array_slice returns a sequence of elements from the array func_get_args with an offset of 1.
I looked up func_get_args and it's supposed to return a copy of the given element(array? object)?? and I guess vsprintf returns a formatted string, removing the string quotations '' ??
October 29th, 2013, 07:31 PM
-
Hi,
this is poor man's database security from the 90s. Don't use this. The mysql_* functions are long obsolete and are about the be removed completely.
Instead, use one of the two contemporary database libraries. They offer real security through so called prepared statements. See this tutorial.
For the sake of completeness: This code takes a query string with placeholders and an arbitrarily long list of values. The values are run through a database escaping function and then inserted into the placeholders. That's what you had to do in early versions of PHP. But it has been replaced with more secure and efficient techniques a decade ago. Unfortunately, a lot of the PHP "tutorials" out there haven't really made it into the 21st century.
If you're interested in the functions, I suggest you try them out.
Last edited by Jacques1; October 29th, 2013 at 07:41 PM.
October 29th, 2013, 07:50 PM
-
Originally Posted by Jacques1
Hi,
this is poor man's database security from the 90s. Don't use this. The
mysql_* functions are long obsolete and are about the be removed completely.
Instead, use one of the two
contemporary database libraries. They offer real security through so called prepared statements. See
this tutorial.
For the sake of completeness: This code takes a query string with placeholders and an arbitrarily long list of values. The values are run through a database escaping function and then inserted into the placeholders. That's what you had to do in early versions of PHP. But it has been replaced with more secure and efficient techniques a decade ago. Unfortunately, a lot of the PHP "tutorials" out there haven't really made it into the 21st century.
If you're interested in the functions, I suggest you try them out.
thank you kid sir....i will look into that
October 29th, 2013, 07:55 PM
-
October 29th, 2013, 09:49 PM
-
Originally Posted by Jacques1
"Kid sir"?
, My apologies kind sir. I've been reading up on PDO , which appears to be better than mysql.If i'm using a local server , is it compatible with mysql??
October 30th, 2013, 06:27 AM
-
I'm not your boss, so no need to call me "sir".
Originally Posted by rhodoscoder
If i'm using a local server , is it compatible with mysql??
PDO is a way of accessing different database systems. MySQL is one of them. So, yes, you can use PDO to access a MySQL database.
October 30th, 2013, 03:19 PM
-
[QUOTE=Jacques1]I'm not your boss, so no need to call me "sir".
sir
sər/Submit
noun
1.
used as a polite or respectful way of addressing a man.
But i promise i won't refer to you like that again.
October 30th, 2013, 03:34 PM
-
Reading up on PDO
S far i know how to establish a connection and using prepared statements . PDO gives error messages that are easy to debug,so far I've caught my silly little mistakes .
PHP Code:
<?php
// post_add.php
try{
if(!empty($_POST)) {
require 'connection.php';
$stmt = $conn->prepare('INSERT INTO posts VALUES (:title, :body)');
$stmt->bindValue(':title', $_POST['title'],PDO::PARAM_STR);
$stmt->bindValue(':body', $_POST['body'],PDO::PARAM_STR);
$title = $_POST['title'];
$body = $_POST['body'];
$stmt->execute( array(
'title:' =>$_POST['title'],
':body' => $_POST['body']
));
echo 'Entry posted. <a href="post_view.php?id='.$db->lastInsertId().'">View</a>';
}
}
catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
<form method="post">
<table>
<tr>
<td><label for="title">Title</label></td>
<td><input name="title" id="title" /></td>
</tr>
<tr>
<td><label for="body">Body</label></td>
<td><textarea name="body" id="body"></textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Post" /></td>
</tr>
</table>
</form>
i keep getting this error
Code:
ERROR: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
October 30th, 2013, 04:24 PM
-
You've mixed up 'title:' and ':title'. And for some reason you're binding the values twice: with bindValue() and in the execute() call. You need to do either or, not both.
Catching the exception to echo the message also makes no sense. Just leave the exception alone, then it will take care of sending the message to the right device. Only catch an exception if you actually wanna fix the error.
The proper code would look something like this:
PHP Code:
<?php
function html_escape($input) {
return htmlspecialchars($input, ENT_COMPAT | ENT_HTML401, 'utf-8');
}
PHP Code:
<?php
// establish database connection
$db_options = array(
PDO::ATTR_EMULATE_PREPARES => false // important! use actual prepared statements (default: emulate prepared statements)
, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // throw exceptions on errors (default: stay silent)
, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC // fetch associative arrays (default: mixed arrays)
);
$database = new PDO('mysql:host=localhost;dbname=YOURDB;charset=utf8', 'YOURUSER', 'YOURPW', $db_options); // important! specify the character encoding in the DSN string, don't use SET NAMES
PHP Code:
<?php
// create prepared statement
$insert_stmt = $database->prepare('
INSERT INTO
posts (title, body)
VALUES
(:title, :body)
');
// bind the values and execute the statement
$insert_stmt->execute(array(
':title' => $_POST['title']
, ':body' => $_POST['body']
));
echo 'Entry posted. <a href="post_view.php?id=' . html_escape($database->lastInsertId()) . '">View</a>';
Comments on this post
October 30th, 2013, 05:07 PM
-
Thank you again, putting the colon behind title: ,I would have never caught that.
Is using
PHP Code:
$stmt->bindValue(':title', $_POST['title'])
;
more secure than
PHP Code:
$stmt->execute( array(':title' => $_POST['title']
Thirdly, i thought PDO::FETCH_ASSOC was the default and not
PDO::FETCH_BOTH.
and why is it necessary to use charset in the connection string??
October 30th, 2013, 06:14 PM
-
Originally Posted by rhodoscoder
more secure than
No, it's the same. The bindValue() method allows you to declare the type of the value, which some database systems may require you to do. But MySQL doesn't care.
Originally Posted by rhodoscoder
and why is it necessary to use charset in the connection string??
You don't need it if you're fine with the default encoding. But if you do wanna change it, you have to do it like that.
Many people use a SET NAMES query to change the encoding. This is incorrect and a huge security risk, because it doesn't notify PDO that the encoding has changed. PDO will still assume the old encoding, and critical functionalities that depend on the encoding (like the quote() method) may stop working.
If you're interested in the details, check this thread.
Comments on this post
October 30th, 2013, 11:58 PM
-
PHP Code:
<?php
// post_add.php
if( isset ($_POST['title']) && ($_POST['body']) && !empty($_POST) ){
require 'connection.php';
$stmt = $conn->prepare('INSERT INTO posts (title,body) VALUES (:title, :body)');
$stmt->bindValue(':title', $_POST['title']);
$stmt->bindValue(':body', $_POST['body']);
$stmt->execute();
echo 'Entry posted. <a href="post_view.php?id='.$conn->lastInsertId().'">View</a>';
}else if(empty($_POST['title']) || empty($_POST['body']) ){
echo "no values entered";
}
?>
As my code is , empty fields are never submitted to my database which was my problem previously and with some research I concorted this code .Now i'm trying to inform the user that the required fields were not filled if the click the submit button before entering anything in them.My code ends up displaying my pseudo (echo) error message right away when the file is loaded, i tried redirects(which were horrible), the joys of being a PHP newbie
.I don't require answers but guidance on how to come to a solution
<I LOVE CODE>
<?PHP I LOVE PHP ?>
October 31st, 2013, 03:57 AM
-
When binding the values like this
PHP Code:
$stmt->execute( array('title' => $_POST['title'] ));
the leading : is not needed. (The SQL string would still have them in as this denotes the 'placeholder' )