how to bind several columns to one variable in PDO like query? - php

I have a variable $search and I want to search for records containing the $search in multiple columns
$query="Select * from products where name LIKE ? OR color LIKE ?"
$stmt = $this->pdo->prepare($query);
$results=$stmt->execute(array("%$search%","%$search%"));
but when I try to execute print_r($results);, I get nothing displayed except for a '1'.The problem perhaps is binding of the $search variable to the query.So I am curious whether there's a way to handle such a situation and what's the best working alternative.Thanks

$results is the success status of the PDOStatement execution; the returned rows are still in the $stmnt object. You need to iterate over the returned rows and print the individually.
while ($row = $stmnt->fetch(PDO::FETCH_ASSOC)) {
print_r($row);
}
will work.

You can also use the following:
while ($row = $stmnt->fetch()) {
echo $row['YOUR COLUMNS NAME HERE'].'<br>';
}
or use bind columns:
$stmt->bindColumn('COLUMN 1 NAME', $variable1);
$stmt->bindColumn('COLUMN 2 NAME', $variable2);
$stmt->bindColumn('COLUMN 3 NAME', $variable3);
//...... GO ON LIKE THIS
$stmt->execute();

Related

Php search Splitting criteria type

I have a php search form with two fields. One for $code another for '$name'.The user uses one or the other, not both.
The submit sends via $_POST.
In the receiving php file I have:
SELECT * FROM list WHERE code = '$code' OR name = '$name' ORDER BY code"
Everything works fine, however I would like that $code is an exact search while $name is wild.
When I try:
SELECT * FROM list WHERE code = '$code' OR name = '%$name%' ORDER BY code
Only $code works while $name gives nothing. I have tried multiple ways. Changing = to LIKE, putting in parentheses etc. But only one way or the other works.
Is there a way I can do this? Or do I have to take another approach?
Thanks
If you only want to accept one or the other, then only add the one you want to test.
Also, when making wild card searches in MySQL, you use LIKE instead of =. We also don't want to add that condition if the value is empty since it would become LIKE '%%', which would match everything.
You should also use parameterized prepared statements instead of injection data directly into your queries.
I've used PDO in my example since it's the easiest database API to use and you didn't mention which you're using. The same can be done with mysqli with some tweaks.
I'm using $pdo as if it contains the PDO instance (database connection) in the below code:
// This will contain the where condition to use
$condition = '';
// This is where we add the values we're matching against
// (this is specifically so we can use prepared statements)
$params = [];
if (!empty($_POST['code'])) {
// We have a value, let's match with code then
$condition = "code = ?";
$params[] = $_POST['code'];
} else if (!empty($_POST['name'])){
// We have a value, let's match with name then
$condition = "name LIKE ?";
// We need to add the wild cards to the value
$params[] = '%' . $_POST['name'] . '%';
}
// Variable to store the results in, if we get any
$results = [];
if ($condition != '') {
// We have a condition, let's prepare the query
$stmt = $pdo->prepare("SELECT * FROM list WHERE " . $condition);
// Let's execute the prepared statement and send in the value:
$stmt->execute($params);
// Get the results as associative arrays
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
The variable $results will now contain the values based on the conditions, or an empty array if no values were passed.
Notice
I haven't tested this exact code IRL, but the logic should be sound.

Select statement fill data in a foreach

I'm trying to create a php file that when clicking a 'Edit' Link it will get that job ID and list the number of rows by jobRef in my applications table.
This is just to list all of the applications for the different jobs i have available on my website.
<?php
require 'mysqlcon.php';
if(isset($_GET['id']))
{
$stmt = $pdo->query('SELECT FROM applications WHERE applicationID = :id');
$results = $stmt->fetchAll();
echo "<table><tr><td>Job Reference</td><td>Job Title</td><td>Job Location</td><td>Job Description</td><td>Salary</td><td>Availability</td> <td>Category</td><td>Apply</td>";
foreach ($results as $row) {
echo "<tr><td>".$row['applicationID']."</td>". "<td>".$row['jobRef']."</td>", "<td>".$row['fName']."</td>", "<td>".$row['lName']."</td>";
}
}
?>
My error is that i cannot get my code to work; I've tried using "PDO::FETCH_ASSOC" but still no help.
Any ideas on where i've gone wrong?
You need to use prepare and execute, for binding/parameterized queries. You also need to pass the value to the query. Try this:
$stmt = $pdo->prepare('SELECT * FROM applications WHERE applicationID = ?');
$stmt->execute(array($_GET['id']));
$results = $stmt->fetchAll();
Your select query also needs the value that your are selecting. I've put in * which is every column. If you only want some columns list them separated by commas.
The concatenation and comma separation in your echo is strange but I think should work..
Final note, your table doesn't close; you should add a </table> after the foreach.
Final additional note for errors use, http://php.net/manual/en/pdo.errorinfo.php.

PDO : What´s the best method to get the result after insert data to database

I´m very new to PDO. I just wonder what´s the best way to get the result when the data insert to the database comletely. I´m looking around in googl. seems like it´s flexible. That makes me wonder what is correct and what is incorrrect way.
Let see example:
$sql = $conn->prepare("INSERT INTO tb_user(user_name, user_email) VALUES(:user_name,:user_email);
$sql->execute(array(':user_name'=>$user_name, ':user_email'=>$user_email));
$affected_rows = $sql->rowCount();
From this script I want to get result if the data is finish to be insert in database.
If it done-->I will echo it like "complete" and send it back to ajax or etc...
I have tried :
if($affected_rows){
echo"YEZZ!! complete";
}
And
$all = $slq->fetchAll();
if(count($all)) {
echo"YEZZ!! complete";
}
And
if ($sql->execute){
echo"YEZZ!! complete";
//this one i know it will double insert data to database because I called it twice//
But I still want to know when can I use this method
And maybe more ways out there which make me crazy and want to know what is the best way to get result if the thing is done:
AFter insert, after delete, after update these 3 statements is the most important to know each.
Any suggestions could be wonderful !
}
}
you could do:
$id = $conn->lastInsertId('IDCOLUMN');
and then execute a query and search for the id
$stmt = $conn->prepare("SELECT * FROM tb_user WHERE IDCOLUMN = :id");
$stmt->execute(array("id", $id);
if($stmt->rowCount() > 0) {
$result = $stmt->fetch(PDO::FETCH_ASSOC);
}
the result variable will contain your last inserted record
Yes, your approach with rowCount() is a right one. Stick with it.

Using PHP with a MySQL db, how can I select everything from a row if i dont know what the columns are?

I have a table but I dont know what the columns are except for 1 column. There is only 1 permanent data value for each row, the rest of the columns are added and removed elsewhere. This isnt a problem for the query, i just do:
SELECT * FROM table
but for the php function bind_result() i need to give it variables for each column, which i do not know.
I think that once I have the columns in an array, I can do anther query and use call_user_func_array to bind the result to the array.
This seems like it would come up a lot so im wondering is there a standard way of doing this?
Couldn't you just do:
$result = mysql_query("SELECT * FROM table");
while ($row = mysql_fetch_assoc($result))
{
foreach ($row as $field => $value)
{
...
}
}
You could do
show columns from table;
And then parse that string to grab your column names.
You can also try the describe command, which is used to list all of the fields in a table and the data format of each field. Usage:
describe TableName;
you can use
$metadata = $prep_statement->result_metadata()
after you executed the statement and then loop through all result fields using something like
while( $field = $metadata->fetch_field() ) { }
the properties of $field are documented here: http://www.php.net/manual/en/mysqli-result.fetch-field.php

how to identify the source table of fields from a mysql query

I have two dynamic tables (tabx and taby) which are created and maintained through a php interface where columns can be added, deleted, renamed etc.
I want to read all columns simulataneously from the two tables like so;-
select * from tabx,taby where ... ;
I want to be able to tell from the result of the query whether each column came from either tabx or taby - is there a way to force mysql to return fully qualified column names e.g. tabx.col1, tabx.col2, taby.coln etc?
In PHP, you can get the field information from the result, like so (stolen from a project I wrote long ago):
/*
Similar to mysql_fetch_assoc(), this function returns an associative array
given a mysql resource, but prepends the table name (or table alias, if
used in the query) to the column name, effectively namespacing the column
names and allowing SELECTS for column names that would otherwise have collided
when building a row's associative array.
*/
function mysql_fetch_assoc_with_table_names($resource) {
// get a numerically indexed row, which includes all fields, even if their names collide
$row = mysql_fetch_row($resource);
if( ! $row)
return $row;
$result = array();
$size = count($row);
for($i = 0; $i < $size; $i++) {
// now fetch the field information
$info = mysql_fetch_field($resource, $i);
$table = $info->table;
$name = $info->name;
// and make an associative array, where the key is $table.$name
$result["$table.$name"] = $row[$i]; // e.g. $result["user.name"] = "Joe Schmoe";
}
return $result;
}
Then you can use it like this:
$resource = mysql_query("SELECT * FROM user JOIN question USING (user_id)");
while($row = mysql_fetch_assoc_with_table_names($resource)) {
echo $row['question.title'] . ' Asked by ' . $row['user.name'] . "\n";
}
So to answer your question directly, the table name data is always sent by MySQL -- It's up to the client to tell you where each column came from. If you really want MySQL to return each column name unambiguously, you will need to modify your queries to do the aliasing explicitly, like #Shabbyrobe suggested.
select * from tabx tx, taby ty where ... ;
Does:
SELECT tabx.*, taby.* FROM tabx, taby WHERE ...
work?
I'm left wondering what you are trying to accomplish. First of all, adding and removing columns from a table is a strange practice; it implies that the schema of your data is changing at run-time.
Furthermore, to query from the two tables at the same time, there should be some kind of relationship between them. Rows in one table should be correlated in some way with rows of the other table. If this is not the case, you're better off doing two separate SELECT queries.
The answer to your question has already been given: SELECT tablename.* to retrieve all the columns from the given table. This may or may not work correctly if there are columns with the same name in both tables; you should look that up in the documentation.
Could you give us more information on the problem you're trying to solve? I think there's a good chance you're going about this the wrong way.
Leaving aside any questions about why you might want to do this, and why you would want to do a cross join here at all, here's the best way I can come up with off the top of my head.
You could try doing an EXPLAIN on each table and build the select statement programatically from the result. Here's a poor example of a script which will give you a dynamically generated field list with aliases. This will increase the number of queries you perform though as each table in the dynamically generated query will cause an EXPLAIN query to be fired (although this could be mitigated with caching fairly easily).
<?php
$pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
function aliasFields($pdo, $table, $delim='__') {
$fields = array();
// gotta sanitise the table name - can't do it with prepared statement
$table = preg_replace('/[^A-z0-9_]/', "", $table);
foreach ($pdo->query("EXPLAIN `".$table."`") as $row) {
$fields[] = $table.'.'.$row['Field'].' as '.$table.$delim.$row['Field'];
}
return $fields;
}
$fieldAliases = array_merge(aliasFields($pdo, 'artist'), aliasFields($pdo, 'event'));
$query = 'SELECT '.implode(', ', $fieldAliases).' FROM artist, event';
echo $query;
The result is a query that looks like this, with the table and column name separated by two underscores (or whatever delimeter you like, see the third parameter to aliasFields()):
// ABOVE PROGRAM'S OUTPUT (assuming database exists)
SELECT artist__artist_id, artist__event_id, artist__artist_name, event__event_id, event__event_name FROM artist, event
From there, when you iterate over the results, you can just do an explode on each field name with the same delimeter to get the table name and field name.
John Douthat's answer is much better than the above. It would only be useful if the field metadata was not returned by the database, as PDO threatens may be the case with some drivers.
Here is a simple snippet for how to do what John suggetsted using PDO instead of mysql_*():
<?php
$pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
$query = 'SELECT artist.*, eventartist.* FROM artist, eventartist LIMIT 1';
$stmt = $pdo->prepare($query);
$stmt->execute();
while ($row = $stmt->fetch()) {
foreach ($row as $key=>$value) {
if (is_int($key)) {
$meta = $stmt->getColumnMeta($key);
echo $meta['table'].".".$meta['name']."<br />";
}
}
}

Categories