I would like to know how to use the common mysql_* stuff. I don't take to make SO a mess and make a question for each one, so I just put up this question with a small list:
num_rows
fetch_array
set_charset
fetch_row
This is the functions you use to normal mysql_* queries, what are the PDO´s functions equals to these?
And how can you INSERT INTO, UPDATE and DELETE
The only thing I know and tested right now is connect to the db + selecting like this:
$conn = new PDO("mysql:host=$host;dbname=$db",$user,$pass);
$sql = "SELECT id FROM users";
$q = $conn->query($sql) or die("failed!");
What I expect for an answer is either links to each function and attributes
(num_rows, fetch_array, insert into, update, etc..) or direct answers to them.
$q = $conn->query($sql) or die("failed!");
Don't do that. Use:
$conn = new PDO("mysql:host=$host;dbname=$db", $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
Then you'll get an exception if something goes wrong with the query.
have a look at the documentation: http://php.net/manual/en/book.pdo.php
Its all in there
Related
Building a tool that first pulls a sim number, then marks it as taken. The first part is working great and is being served to my page with ajax. The second part doesn't seem to want to work.
include_once 'inc/db_connect.php';
$stmt = $db->query('SELECT sim FROM p2p WHERE taken = 0 ORDER by id ASC LIMIT 1');
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$result = $row['sim'];
}
echo json_encode($result);
$stmt = $db->prepare("UPDATE p2p SET taken = 1 WHERE sim = ?");
$stmt->bind_param('i', $result);
$stmt->execute();
Any ideas!
It's because of this bind_param() that is MySQLi_* syntax and you're using PDO.
fetch(PDO::FETCH_ASSOC)
Use PDO's bindParam() function
Those two APIs do not mix.
If that doesn't work, use bindValue()
Add $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); right after the connection is opened. That will signal the error.
An insight
I've noticed in a previous question you posted, that you are using mysqli_* functions to connect to your database with.
$result = mysqli_query($conn, $query);
If that is still the case, then you cannot mix PDO with mysqli_ in any way, shape or form.
Those MySQL APIs do not intermix with each other.
Consult: http://php.net/manual/en/mysqlinfo.api.choosing.php
I have a simple scenario: a user connects to "get.php?city=london", the server then searches the MySQL database for the data matching that request and outputs it.
I am using the following code to do this:
<?php
$con = mysql_connect( 'localhost', 'user', 'pass') or die('Could not connect to mysql server.' );
mysql_select_db('mydb', $con) or die('Could not select database.');
if(!isset($city)) return;
$c=$_GET["city"];
$q = "select * FROM cities WHERE city = '{$c}'";
$re = mysql_query($q);
... etc
Is it secure to simply insert the GET variable into the query like this? Will this make me vulnerable to a MySQL injection? Is there a more secure way to do this?
Regards
UPDATE:
would that be more secure?:
if(!isset($city)) return;
$city=$_GET["city"];
$q = "SELECT row1, row2 WHERE city= ?;";
$mysqli = new mysqli('localhost', 'root', 'pass', 'dbname');
$stmt = $mysqli->stmt_init();
if($stmt->prepare($q)){
$stmt->bind_param("s", mysql_real_escape_string($city));
$stmt->execute();
$stmt->bind_result($row1, $row2);
while ($stmt->fetch()) {
//do stuff with the data in the $row array
}
$stmt->close();
}
It's not secure at all, GET requests can be faked by simply changing the web address.
Trusting user input is dangerous. Someone could change the value of the city parameter, inject SQL into your query, and gain access to your data. You should be using prepared statements. That means that you need to use either the mysqli extension or the PDO extension.
I recommend using the PDO extension, mainly because it allows you to switch databases in the future without having to re-write all the code.
No they are not in mysql_* functions. You need to sensitize them using mysql_real_escape_string.
Better to use PDO with bindParams and the PDO library will do it for you.
php.net/pdo_mysql
http://in3.php.net/manual/en/pdostatement.bindparam.php
If you use mysql_real_escape_string user couldn't pass a string to mysql injection. On that purpose, for cities, I think there are not problem to use GET. However if you use personal user information I would use $_POST
I'm new to PDO. I would like to know if there is anything similar to mysql_select_db in PDO, so that i can switch between different databases during runtime without the need for creating a new object.
I know that I am a couple of months late but you should be able to switch between databases from within your query.
examples:
$sql = "SELECT * FROM dbname.tablename";
$sql = "SELECT * FROM anotherdbname.anothertablename"
So even if your original $pdo object was used 'blahblah' as the dbname, you should still be okay based on the select examples I provided.
It looks like PDO does not have database switching because not every database engine supports it.
AFAIK PostgreSQL does not have database switching, but offer schemas and u can switch between those.
However if you're using mysql check if this works for you:
$pdo = new PDO('mysql:dbname=db1;host=127.0.0.1','user','pass');
$sql = 'select count(*) from table_name';
$res = $pdo->query($sql);
print_r($res->fetchAll());
$pdo->exec('USE db2');
$res = $pdo->query($sql);
print_r($res->fetchAll());
You actually do not need to specify the database upon connection at all. As long as you specify the database in every query, as Laz stated, this will work:
$dbh = new PDO('mysql:host=127.0.0.1','USER','PASS');
$query = "SELECT * FROM database1.table1";
$query = "SELECT * FROM database2.table1";
There is not, you will need to create two PDO objects for the separate connections if you would like to use both at runtime.
Edit: Interesting point by #laz below (which I'm guessing is the cause of negative votes on my answer). I was thinking under the assumption that the databases were on separate servers tbh, in which case my answer stands.
you don't even need to specify the database in every query, just use msyql syntax
USE db_name
and then write your requests
you can make this :
$database1 = new PDO("mysql:host=localhost;dbname=db1;charset=utf8;",$username, $password);
$database2 = new PDO("mysql:host=localhost;dbname=db2;charset=utf8;",$username, $password);
simple 😀
I've seen this code that's been floating around, and also the fixed? version. Basically I've gotten this to work:
mysql_connect("host","client_name","client_pw");
mysql_select_db("database");
$q=mysql_query("SELECT * FROM table");
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
mysql_close();
but for some reason I feel it should be in mysqli. I'm new, and tried to write an equivalent mysqli OO code:
$mysqli = new mysqli("host", "client_name", "client_pw");
$mysqli->select_db("database");
$q = "SELECT * FROM table";
while($e=$mysqli->fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
mysql_close();
It fails. I've tried other combinations, such as preparing a query and executing it, and setting that as $e, but all fail.
Do I have to manually build the array for the json_encode or something?
Maybe a better question is why I want to reinvent the wheel, but this has been bothering me.
Ah, I see you are not one with the database. Let us perform an exercise.
Close your eyes, breathe in, breathe out.
Relax.
You are one with the database.
You are one with the code.
Repeat after me.
Prepare.
Bind.
Execute.
Repeat it.
Again.
This is your new mantra, my friend.
You've accidentally skipped a step in your existing code. Let's throw it out and start over.
I am going to show you how to use PDO, one of the better ways PHP has to communicate with a database. It's less convoluted than the mysqli extension.
// Make sure these variables contain the correct data.
$pdo = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
// Ask PDO to throw exceptions instead of warnings.
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Here's our SQL. We're getting back a PDOStatement object here.
$sh = $pdo->prepare('SELECT * FROM Foo WHERE bar = ?');
// That question mark is a placeholder. bindValue lets us replace the question mark
// with the specified data. This is called a prepared statement. The end result is
// *complete and total immunity* from SQL Injection, if performed correctly.
$sh->bindValue(1, "I'm looking for a bar that is equal to this.");
// Okay, we've bound everything, let's run the query.
$sh->execute();
// And assuming there are no errors (note my severe lack of error handling),
// we should now have our complete list of data from the database.
print_r($sh->fetchAll(PDO::FETCH_ASSOC));
// Alternatively, we could pass bound variables as an array to execute:
$sh = $pdo->prepare('SELECT * FROM Foo WHERE bar = ?');
$sh->execute(array( "I'm a bar!" ));
// And of course, we can use variables in the binding...
$bar = 746;
$sh = $pdo->prepare('SELECT * FROM Foo WHERE bar = ?');
$sh->bindValue(1, $bar);
$sh->execute();
PDO's support for prepared statements and placeholders makes it one of the best choices for database access in modern PHP.
(mysqli also has access to prepared statements, but it forces you to also bind result variables, and that can be damned awkward under a lot of circumstances.)
fetchAll(PDO::FETCH_ASSOC) returns a multidimensional array. The outer array is numerically indexed, each value being a row. Each row is a string-keyed array, where the keys are column names and the values are the data from the database. There are a few other things that fetchAll can do, though I haven't found many of them to be useful. You can also fetch one row at a time
You can probably pass the results directly to json_encode, if you'd like, and not suffer too many problems.
Understand that you will want to add appropriate error detection to this code. I have omitted it here for brevity.
try
{
$db = new mysqli("your_host_ip", "your_username", "your_pass", "your_db", 3306);
if ($db->connect_errno) throw new exception(sprintf("Could not connect: %s", $db->connect_error));
$sqlCmd = "select * from users order by username";
$result = $db->query($sqlCmd);
if(!$result) throw new exception(sprintf("Invalid query : %s", $sqlCmd));
...
$q=mysql_query("SELECT * FROM table");
Here is how to do it with mysqli OOP
After the line $q= etc. -add the following code..
<?php
$result=$mysqli->query($q);
while($e=$result->fetch_assoc()){
$output[]=$e;
}
print(json_encode($output));
?>
Generally I connect and retrieve data using the standard way (error checking removed for simplicity):
$db = mysql_select_db("dbname", mysql_connect("host","username","passord"));
$items = mysql_query("SELECT * FROM $db");
while($item = mysql_fetch_array($items)) {
my_function($item[rowname]);
}
Where my_function does some useful things witht that particular row.
What is the equivalent code using objects?
Since version 5.1, PHP is shipped with the PDO driver, which gives a class for prepared statements.
$dbh = new PDO("mysql:host=$hostname;dbname=$db", $username, $password); //connect to the database
//each :keyword represents a parameter or value to be bound later
$query= $dbh->prepare('SELECT * FROM users WHERE id = :id AND password = :pass');
# Variables are set here.
$query->bindParam(':id', $id); // this is a pass by reference
$query->bindValue(':pass', $pass); // this is a pass by value
$query->execute(); // query is run
// to get all the data at once
$res = $query->fetchall();
print_r($res);
see PDO driver at php.net
Note that this way (with prepared statements) will automatically escape all that needs to be and is one of the safest ways to execute mysql queries, as long as you use binbParam or bindValue.
There is also the mysqli extension to do a similar task, but I personally find PDO to be cleaner.
What going this whole way around and using all these steps gives you is possibly a better solution than anything else when it comes to PHP.
You can then use $query->fetchobject to retrieve your data as an object.
You can use the mysql_fetch_object()
http://is2.php.net/manual/en/function.mysql-fetch-object.php