php cant insert array data into database - php

the sql :
$sql = $db->prepare('SELECT * FROM product_detail WHERE size = $order_size AND product_id = $order_detail_product_id');
the code:
$order_detail_product_id = $_POST['order']['product_id'];
$order_size = $_POST['order']['size'];
html:
<?php foreach ($it as $e) { >?
<input type="text" name="order[product_id][]" value="<?php echo $e[0]; ?>">
<input type="text" name="order[size][]" value="<?php echo $e[3]; ?>">
<?php } ?>
why that's can't work. the error is array to string conversion

You can't use variables like that inside single quotes in your prepare statement (you'd need double quotes for that to make sense, but it'd still be quite bad and still doesn't make sense cause you're using an array as a string), and also putting the value inside the string you prepare beats the purpose of preparing, you should do:
foreach ($order_size as $key => $size):
$stmt = $db->prepare('SELECT * FROM product_detail WHERE size = ? AND product_id = ?');
$stmt->bindParam(1, $size);
$stmt->bindParam(2, $order_detail_product_id[$key]);
...
endforeach;
Or a different query, depending on what you want, which is not easy to guess with what you posted.
Assuming you're using pdo and not mysqli (which would suck).

Related

search dynamically PHP MYSQL PDO

I have a form with 3 select boxes: age,room,type.
<form action="results.php" method="get">
<div class="form-group">
<select name="age">
<option value>Any</option>
<option value="1">15</option>
<option value="2">25</option>
<option value="3">30</option>
<option value="4">40</option>
</select>
</div>
<div class="form-group">
<select name="room">
<option value>Any</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
<div class="form-group">
<select name="type">
<option value>Any</option>
<option value="1">Personal</option>
<option value="2">Business</option>
</select>
</div>
</form>
What i am trying to do with PDO is to make a small search.
If all variables are empty then my condition is:
$search = $db->query("SELECT * FROM table");
If 1 of them (as example the age) is not empty then i have:
if(!empty($_GET['age'])){
$age = $_GET['age'];
$search = $db->query("SELECT * FROM table WHERE age = '$age'");
}
Now, if 2 of them are npt empty i have:
if(!empty($_GET['age']) && !empty($GET['room'])){
$age = $_GET['age'];
$room = $_GET['room'];
$search = $db->query("SELECT * FROM table WHERE age = '$age' AND room = '$room'");
}
In order to avoid all possible search combinations, how can i make a search with the term if is not empty. I had made one in the past:
if(!empty($age)){
$where = "WHERE age = '$age'";
}
if(!empty($room)){
$where .= "and room = '$room'";
}
$query = "SELECT * FROM table $where";
How can i make it happen with PDO?? :/
I'd do something like this:
$param = array();
$query = 'SELECT ... FROM t WHERE 1=1';
if(!empty($_GET['age'])){
$param['age'] = $_GET['age'];
$query .= ' AND t.age = :age';
}
if(!empty($_GET['room'])){
$param['room'] = $_GET['room'];
$query .= ' AND t.room = :room';
}
if(!empty($_GET['type'])){
$param['type'] = $_GET['type'];
$query .= ' AND t.type = :type';
}
$dbh->prepare($query)->execute($param);
You might want to separate out the prepare and the execute. Check the return from the prepare before you try calling execute. Or, configure PDO can throw an exception when an error occurs, e.g.
$dbh->setAttribute(PDO::ERRMODE_EXCEPTION);
You will need to make a query builder of some kind. You will also want to use prepared statements, rather than directly injecting user-provided input into the sql query. That might look something like this:
<?php
$search = [
'age' => 42,
'room' => 'Millyway',
];
$criteria = [];
$params = [];
foreach($search as $field => $value) {
$criteria[] = "$field = :$field";
$params[$field] = $value;
}
$where = ($criteria ? ('WHERE ' . implode(' AND ', $criteria)) : '');
$query = "SELECT * FROM tablename $where";
$stmt = $db->prepare($query);
$stmt->execute($params);
while($obj = $stmt->fetchObject()) {
// iterate over your result set
}
Given search terms as key-values in $search (which can be any column and value in the table, and will need to be populated from wherever those values come from), this code will build $criteria, a set of WHERE clause fragments (using a parameterized sql parameter name, rather than injecting the value directly), and $params, the list of parameters to be passed into the (upcoming) prepared statement.
It then builds the full WHERE clause in $where, by either combining all of the $criteria that were built, or returning an empty string. This is then added directly into the query, and the query is executed using the parameters array that was built up. You then iterate over the result set like any other PDO query.
Among others, the main benefit of using parameterized SQL over injecting variables directly is that it protects you from SQL Injection attacks.
Note that there are many ways this code could be improved. You could easily put it in a function; add complexity to allow for different types of comparisons (e.g. <> or LIKE); even use it as the basis for a more complicated query builder that allows more complicated logic such as ((age = :age AND room = :room1) OR (room = :room2)); and so on. What you do is up to the needs of your application.

mysql select query using imploded values

I have to following situation: I'm making a search page. The search page is populated with MySQL select query selectboxes. Therefor the name of the checkboxes are like name="name[]".
To show you what I'm doing, I'll include a picture:
So if I were to check 1 Availability - like Week - the query will work perfectly. But if I choose 2 Availabilities, only the models with BOTH availabilites show instead of every model that has one of both availabilities.
Here is my code:
HTML:
$return2 = $tafel->query("SELECT DISTINCT whenpossible FROM models where arttype LIKE 'Model%'");
while($row1 = $return2->fetch(PDO::FETCH_ASSOC)){
$whenp = $row1['whenpossible'];
<input type="checkbox" name="when[]" value="<?= $whenp ?>"><span class="box2"><?= $whenp ?></span>
PHP:
if (!empty($_POST['gender'])) {
$genders = $_POST['gender'];
$gender = implode(",",$genders);
} else {
$gender = "%";
}
$select = $tafel->prepare("SELECT * FROM models
WHERE whenpossible LIKE :when");
$select->bindParam(':when', $when, PDO::PARAM_STR);
$select->execute();
Does anyone have an idea how to fix this so that I can choose either 1 or multiple options?
Thank you all very much!
In code you build incorrect SQL command.
For your example SQL is
SELECT * FROM table WHERE field LIKE '%value1,%value2'
This is wrong code. Correct code can be
SELECT * FROM table WHERE field LIKE '%value1' OR field LIKE '%value2'
You should rewrite your code for build correct SQL
For those who are interested or facing the same problem, here is the answer:
In case IN or FIND_IN_SET aren't working for you, you can try this.
Implode your value like so:
if (!empty($_POST['VALUE'])) {
$value = $_POST['VALUE'];
$valueimplode = implode('|', $value)
} else {
$value = 'somethingelse'
}
| is very important for the SQL function. It acts like OR.
SQL as followed:
$query = $db->prepare("SELECT * FROM table WHERE column REGEXP(:valueimplode)");
$query->bindParam(':value', $valueimplode, PDO::PARAM_STR);
$query->execute();
You will find all the results that you need.
If you have an empty value, you can do this:
if (!empty($_POST['VALUE'])) {
$value = $_POST['VALUE'];
$valueimplode = implode('|', $value)
} else {
$value = '%' <-- Wildcard, means EVERYTHING!!!
}
Then the SQL like this:
$query = $db->prepare("SELECT * FROM table WHERE (column REGEXP(:valueimplode) OR column LIKE :value)");
$query->bindParam(':value', $valueimplode, PDO::PARAM_STR);
$query->execute();
% doesn't work with REGEXP so it will go to LIKE, which will then select everything in that column. Meaning, it will result everything.
I hope someone has good use for this!

Use a function to insert 2 queries in mysql

Currently I am trying to write a single function in my php script that adds a new page into my database and updates the navigation table at the same time. For some reason both queries are failing, and I'm not sure what else I should do.
This is my add_content function call:
elseif ($react == "add_content") {
echo 'add content';
$title = $_POST['title'];
$content = $_POST['content'];
$page = $_POST['page'];
if (!empty($title) && !empty($content) && !empty($page)) {
addcontent($title, $content, $page);
} else {
echo 'not enough info';
}
and this is my function:
function addcontent($title, $content, $page) {
global $db;
$query1 = "INSERT INTO `content`(`title`, `content`) VALUES (:title, :content)";
$query2 = "INSERT INTO `navigation` ('page', 'content_id') SELECT :page, c.content_id FROM content c WHERE title=:page;";
try {
$stat = $db->prepare($query1);
$stmt = $db->prepare($query2);
$stat->bindParam(':title', $title);
$stat->bindParam(':content', $content);
$stat->bindParam(':page', $page);
$stat->execute($query1);
$stmt->execute($query2);
$result = "<strong>$title</strong> added<p>";
} catch (Exception $ex) {
$result = "$title deltetion failed";
}
}
I know the two queries work because I've already tested them with dummy information, it's just getting them to work inside of this function that's causing the problem.
I'm not sure if this is needed, but just in case, this is my table to add content:
<form method="POST" action="index.php">
<input type="hidden" name="react" value="add_content">
<input type="hidden" name="page|title" value="admin">
<div align="center"><center><p>ADD A New Page<br>
Title: <input type="text" name="title|page" size="20"><br>
Content: <input type="text" name="content" size="20"><br>
<input type="submit" value="Submit"></p></center></div>
</form>
$query2 = "INSERT INTO `navigation` ('page', 'content_id')
SELECT :page, c.content_id FROM content c WHERE title=:page;";
^ column name marker
You can't use markers for column names. From the docs
The markers are legal only in certain places in SQL statements. For
example, they are allowed in the VALUES() list of an INSERT statement
(to specify column values for a row), or in a comparison with a column
in a WHERE clause to specify a comparison value. However, they are not
allowed for identifiers (such as table or column names), in the select
list that names the columns to be returned by a SELECT statement), or
to specify both operands of a binary operator such as the = equal
sign. The latter restriction is necessary because it would be
impossible to determine the parameter type. In general, parameters are
legal only in Data Manipulation Language (DML) statements, and not in
Data Definition Language (DDL) statements.
If you're trying to select the constant $page you can select c.title because your where condition guarantees that it will be equal to $page.
$query2 = "INSERT INTO `navigation` ('page', 'content_id')
SELECT c.title, c.content_id FROM content c WHERE title=:page;";
Also, you're binding $page to the wrong statement
$stat->bindParam(':page', $page);
Change it to
$stmt->bindParam(':page', $page);
^

PHP PDO resulting in "Array" value rather than actual value

I have created a form which queries a MySQL database and displays results. Now I want to be able to filter my results. I have:
<input type="checkbox" name="multi_cif[]" value="<?php echo $g1 ?>"><font size="1" face="Arial, Helvetica, sans-serif">
In the output which is displaying all results via foreach and the variable $g1 is a MySQL query value (address). I want to be able to click these check boxes next to the results so when the user clicks the button labeled "Filter" only the results checked are displayed.
So far my code is as follows:
<?PHP
if (isset($_POST['Submit2']))
{
$stmt = $dbh->prepare('SELECT * FROM CIF WHERE address LIKE ?');
$stmt->execute(array("%$_POST[multi_cif]%"));
//$stmt->execute(array(":term" => "%" . $_POST["multi_cif"] . "%"));
//$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
/*while ($results = $stmt->fetch()) //WILL UNCOMENT AND ADD OR LIKE AFTER SINGLE QUERY WORKING
{
echo $results['address'];
echo $results['alternativeid'];
}*/
print_r($_POST);
$results = $stmt->fetch();
echo $results['address'];
echo $results['alternativeid'];
}
?>
The commented out stuff is other things I have tried. I am very close to my results. The results of the following code ends in:
[multi_cif] => Array ( [0] => test.13ann.com [1] => testfortestltd444557.com.tw ) ) coralarray.ruhttp://mirror3.malwaredomains.com/files/domains.txt
So clearly "Array" is being passed as a value instead of the desired address assigned to multi[]. Could someone please explain why this is and help me fix it? I am new to PDO as of yesterday but have chosen to use it and re-work my other statements to implement prepared statements instead of dynamically building them. Thanks in advance!
Edited: I took some of Brad's advice but kept the statement without the additional "OR address LIKE ?" as right now I am only clicking one checkbox but still getting "Array" instead of "test.13.ann.com" Once I figure out why "Array" vs. value I will add the additional OR --thanks Brad for pointing out!
Try accessing the first array value, rather than the outer array -
$stmt->execute(array("%{$_POST['multi_cif'][0]}%"));
to do it dynamically you could try
// create n number of placeholders based off number of $_POST['multi_cif']
$place_holders = implode(' OR', array_fill(0, count($_POST['multi_cif']), ' address LIKE ?'));
// create n number of values based off number of $_POST['multi_cif']
$values = '"%'. implode('%","%', $_POST['multi_cif']).'%"';
// explode the values into an array
$values = explode(',',$values);
$stmt = $dbh->prepare("SELECT * FROM CIF WHERE $place_holders");
$stmt->execute(array($values));
You were nearly there. You didn't concatenate your parameter correctly.
Try
<?php
if (isset($_POST['Submit2']))
{
$term = "%" . $_POST["multi_cif"] . "%";
$stmt = $dbh->prepare('SELECT * FROM CIF WHERE address LIKE ?');
$stmt->execute(array($term));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($rows = $stmt->fetch())
{
echo $results['address'];
echo $results['alternativeid'];
}
}
?>

how to loop through a set of GET values in php

I'm making a simple online store like program. What can you suggest that I would do so that I can loop through the inputs I've made in my program.
I'm still using get so that I could see how the data looks like, I'll change it to post later.
This is what the url looks like, when I commit the buying of all the products added in the cart:
http://localhost/pos/php/checkout.php?ids=2;&qoh=12;&qbuys=&ids=6;&qoh=2304;&qbuys=304&ids=4;&qoh=699;&qbuys=99
This is the code that I'm using to commit only one product, it doesn't work when I had something like in the above url:
<?php
$id=$_GET['ids'];
$qtyhnd=$_GET['qoh'];
$qtytbuy=$_GET['qbuys'];
$left=$qtyhnd-$qtytbuy;
if($qtyhnd>=$qtytbuy){
$update=query_database("UPDATE prod_table SET QTYHAND='$left' WHERE PID='$id'", "onstor", $link);
}
?>
Please comment if you need more details,thanks
Either convert the parameters to array parameters (e.g. qoh[]) and then iterate in parallel, or parse the query string manually.
You have semicolons after some values maybe you should pass just the integer this are qoh and qbuys.
Apart of that you should use mysql_real_escape_string() and (int) before integer values to prevent SQL injection e.g.:
$int = (int)$_GET['price'];
$string = $_GET['val'];
mysql_real_escape_string($string);
Also if you want to pass multiple values you have to use array for them:
HTML
<input type="hidden" name="ids[]" value="1">
<input type="hidden" name="ids[]" value="2">
<input type="hidden" name="ids[]" value="3">
PHP
$ids = $_GET['ids'];
foreach($ids as $id) {
$sql = 'UPDATE table SET field=? WHERE id='.(int)$id;
....
}
You can use the $_SERVER['QUERY_STRING'] with foreach loop like this:
foreach($_SERVER['QUERY_STRING'] as $key => $value){
echo "$key - $value <br />";
}
This way you can get the values of GET and use in your database query in similar fashion using foreach loop.
I assume that PID in prod_table is of integer type. Doesn't $id variable contain "2;" instead of 2? Anyway, what kind of error do you get?
Have your url like
http://localhost/pos/php/checkout.php?ids[]=2&qoh[]=12&qbuys[]=&ids[]=6&qoh[]=2304&qbuys[]=304&ids[]=4&qoh[]=699&qbuys[]=99... using a HTML structure like infinity pointed out.
Then:
foreach ($_GET['ids'] as $k => $v) {
$id = (int)$v;
$qtyhnd = (int)$_GET['qoh'][$k];
$qtytbuy = (int)$_GET['qbuys'][$k];
$left = $qtyhnd - $qtytbuy;
if ($qtyhnd >= $qtytbuy) {
$update = query_database(
"UPDATE prod_table SET QTYHAND='$left' WHERE PID='$id'",
"onstor",
$link);
}
}
And if the database type of QTYHAND and PID are int, exclude single quotes (') from your SQL queries.

Categories