magento make multiple database connections without losing array values - php

I am trying to make connections to two different databases so my script should work as follows
Find all orders for the current logged in customer where the order state is complete, it is a virtual product and it has a juno order id (this query works fine)
Collect all of order ids that have been found and store them in an array (this works fine)
now connect to sales_order_items and for each item that is part of an order id check to see if the database has a url download link,
if not i will connect to an api --
the problem is when i want to make my second connection i seem to lose all the values that are stored in the $orderIds array.
i have been looking for solutions but i am pretty new to the zend framework
any help would be much appreciated
my script is as follows
$conn = Mage::getSingleton('core/resource')->getConnection('core_write');
$result = $conn->query('select * from sales_flat_order WHERE customer_id='.$session->getCustomerId().' AND state="complete" AND is_virtual=1 AND juno_order_id!="null"');
$orderIds=array();
foreach ($result as $orderId)
{
$orderIds[]=$orderId[entity_id];
$itemsonOrder=$conn->query('select * from sales_flat_order_items WHERE order_id='.$order[entity_id]);
}
// value of first array $orderIds gets lost if i make annother connection using $conn
echo 'items on order';
print_r($itemsonOrder);
echo '<pre>';
print_r($orderIds);
echo '</pre>';

Well you aren't done with the first query yet when you are connecting with the second query. Go ahead and finish with the first query, then start the second one. Try something more like this...
$conn = Mage::getSingleton('core/resource')->getConnection('core_write');
$result = $conn->query('select * from sales_flat_order WHERE customer_id='.$session->getCustomerId().' AND state="complete" AND is_virtual=1 AND juno_order_id!="null"');
$orderIds=array();
foreach ($result as $orderId)
{
$orderIds[]=$orderId[entity_id];
}
foreach ($orderIds as $orderId)
{
$itemsonOrder=$conn->query('select * from sales_flat_order_items WHERE order_id='.$orderId);
}
Also, you should probably make sure you are using parameters when doing queries. Concatenating sql strings like that can be dangerous (leaves you open to vulnerabilities sometimes). For example,
$conn->query('select * from sales_flat_order_items WHERE order_id='.$orderId);
should be changed to
$conn->query('select * from sales_flat_order_items WHERE order_id=?', array($orderId));
Also, do you really need to "select *"??? I mean, just select the columns you need.

Related

Check if value is found in SQL table within PHP script?

I need to be able to check and see in a certain string is anywhere within my SQL table. The table I am using only has one column of char's. Right now it is saying that everything entered is already within the table, even when it actually is not.
Within SQL I am getting the rows that have the word using this:
SELECT * FROM ADDRESSES WHERE STREET LIKE '%streeetName%';
However, in PHP the word is being entered by the user, and then I am storing it as a variable, and then trying to figure out a way to see if that variable is somewhere within the table.
$duplicate = mysql_query("SELECT * FROM ADDRESSES WHERE STREET_NAME LIKE '%$streetName%'", $connect);
if(!empty($duplicate))
{
echo "Sorry, only one of each address allowed.<br /><hr>";
}
You need to do a little bit more than building the query, as mysql_query only returns the resource, which doesn't give you any information about the actual result. Using something like mysql_num_rows should work.
$duplicate = mysql_query("SELECT * FROM ADDRESSES WHERE STREET_NAME LIKE '%$streetName%'", $connect);
if(mysql_num_rows($duplicate))
{
echo "Sorry, only one comment per person.<br /><hr>";
}
Note: the mysql_* functions are deprecated and even removed in PHP 7. You should use PDO instead.
In the SQL you used
%streeetName%
But in the query string below, you used
%$streeetName%
Change the correct one
$duplicate = mysql_query("SELECT * FROM ADDRESSES WHERE STREET_NAME LIKE '%$streetName%'", $connect);
if(!empty($duplicate))
{
echo "Sorry, only one comment per person.<br /><hr>";
}
if($results->num_rows) is what you need to check if you have results back from your query. An example of connection and query, check, then print or error handle, the code is loose and not checked for errors. Best of luck...
//Typically your db connect will come from an includes and/or class User...
$db = new mysqli('localhost','user','pass','database');
$sql = "SELECT * FROM `addresses` WHERE `street_name` LIKE '%$streetName%'",$connect;
//test your queries in PHPMyAdmin SQL to make sure they are properly configured.
//store the results of your query in a variable
$results = $db->query($sql);
$stmt = '';//empty variable to hold the values of the query as it runs through the while loop
###########################################################
#check to see if you received results back from your query#
###########################################################
if($results->num_rows){
//loop through your results and echo or assign the values as needed
while($row = $results->fetch_assoc()){
echo "Street Name: ".$row['STREET_NAME'];
//define more variables from your DB query using the $row[] array.
//concatenate values to a variable for printing in your choice further down the document.
$address .= $row['STREET_NAME'].' '.$row['CITY'].' '$row['STATE'].' '$row['ZIP'];
}
}else{ ERROR HANDLING }

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.

mysqli query in WHILE loop

1.) Can you nest a msqli_query inside a while loop?
2.) If yes, why would the PHP below not write any data to the precords table?
If I echo a $build array variable it shows properly, but the mysqli insert writes nothing to the table in the DB. THe code does not error out anywhere, so what am I missing about this?
$data = mysqli_query($con,"SELECT * FROM Cart WHERE Buyer_ID='$_SESSION[cid]' AND Cart_Date='$_SESSION[cdate]'");
while($build = mysqli_fetch_array($data))
{
//echo $build[idex]."<br>";
mysqli_query($con,"INSERT INTO precords (precord,Buyer_ID,Account,Purchase_Date,Item_Number,Item_Qty,Item_Title,Item_FPrice,Item_FFLFlag,ccpass) VALUES ('$build[idex]','$build[Buyer_ID]','$build[Cart_Date]','$build[Item_Number]','$build[Item_Qty]','$build[Item_Title]','$build[Item_FPrice]','$build[Item_FFLFlag]','N')");
};
Thanks for any help.
** P.S. - This code is meant to move certain values from a TEMPORARY table/session variables, over to a permanent record table, but the loop is needed since there is more than one product in the cart associated with the user/session.
yes you can use it in a loop and
you may wanna add mysql_error() function to find out what's wrong with it and try to fix it or by adding the error to the question so we can tell you what to do
$data = mysqli_query($con,"SELECT * FROM Cart WHERE Buyer_ID='$_SESSION[cid]' AND Cart_Date='$_SESSION[cdate]'");
while($build = mysqli_fetch_array($data))
{
// echo $build[idex]."<br>";
mysqli_query($con,"INSERT INTO precords(precord,Buyer_ID,Account,Purchase_Date,Item_Number,Item_Qty,Item_Title,Item_FPrice,Item_FFLFlag,ccpass)
VALUES ('$build[idex]','$build[Buyer_ID]','$build[Cart_Date]','$build[Item_Number]','$build[Item_Qty]','$build[Item_Title]','$build[Item_FPrice]','$build[Item_FFLFlag]','N')")
or die (mysql_error());
};
in a simplified form when you want to fetch data from a database to display in html list I intentionally added mysqli ORDER BY which have only two order ASC[ascending] and DESC[descending] and I also used mysqli LIMIT which i set to 3 meaning that number of result fetch from the database should be three rows only
I concur with the answer of ali alomoulim
https://stackoverflow.com/users/2572853/ali-almoullim
MY SIMPLIFIED CODE FOR THE LOOPING WHILE MYSQLI ORDER BY AND LIMIT
$usersQuery = "SELECT * FROM account ORDER BY acc_id DESC LIMIT 3";
$usersResult=mysqli_query($connect,$usersQuery);
while($rowUser = mysqli_fetch_array($usersResult)){
echo $rowUser["acc_fullname"];
}

php mysql alternative to using same query again inside a loop [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to query a tree structure table in MySQL in a single query, to any depth?
I have an admin area I created that pulls data from the mysql database using php and display the results in a table. Basically it shows a parent category, then the first sub category below it, then the third level sub category/subject.
It works perfectly but as I am new to mysql and php I am sure that it the code needs to be improved in order to save db resources as while building the table I use 3 while loops and in each loop make a mysql query which I am sure is the wrong way to do it.
Can somebody offer me some assistance for the best way of doing this?
Here is the code:
$query = mysql_query("SELECT * FROM categories WHERE
parent_id is null
order by cat_id asc;", $hd)
or die ("Unable to run query");
while ($row = mysql_fetch_assoc($query)) {
echo '<tr style="font-weight:bold;color:green;"><td>'. $row ['cat_id'].'</td><td>'.$row['cat_name'].'</td><td>'.$row ['parent_id'].'</td><td>'.$row['active'].'</td><td>'.$row ['url'].'</td><td>'.$row['date_updated'].'</td></tr>' ;
$query2 = mysql_query("SELECT * FROM categories WHERE
(active = 'true' AND parent_id = ".$row ['cat_id'].")
order by cat_id asc;", $hd)
or die ("Unable to run query");
while ($row2 = mysql_fetch_assoc($query2)) {
echo '<tr style="font-weight:bold;"><td>'. $row2['cat_id'].'</td><td>'.$row2 ['cat_name'].'</td><td>'.$row2['parent_id'].'</td><td>'.$row2 ['active'].'</td><td>'.$row2['url'].'</td><td>'.$row2 ['date_updated'].'</td></tr>' ;
$query3 = mysql_query("SELECT * FROM categories WHERE
(active = 'true' AND parent_id = ".$row2 ['cat_id'].")
order by cat_id asc;", $hd)
or die ("Unable to run query");
while ($row3 = mysql_fetch_assoc($query3)) {
echo '<tr><td>'. $row3['cat_id'].'</td><td>'.$row3['cat_name'].'</td><td>'.$row3 ['parent_id'].'</td><td>'.$row3['active'].'</td><td>'.$row3 ['url'].'</td><td>'.$row3['date_updated'].'</td></tr>' ;
}
}
}
EDIT
Ok so I did a bit of research and this is where I am:
Probably for a small database my approach is fine.
For a bigger database using an array to store the data would probably mean I need to use a recursive approach which might use up too much memory. Would love to hear what people think, would it still be better than looping db queries in the nested while loops?
I found the following thread where there is an answer to do this without reccursion and with only one query. Not sure if I need to add a position column to my current design:
How to build unlimited level of menu through PHP and mysql
If I rebuild the design using the nested sets model instead of adjacency model then the mysql query would return the results in the required order however maintaining the nested sets design is above my head and I think would be overkill.
That's it. If anyone has any input on top of that please add to the conversation. There must be a winning approach as this kind of requirement must be needed for loads of web applications.
I would think you could do something like this:
SELECT * FROM categories
WHERE active = 'true'
ORDER BY parent_id, cat_id
This would give you all your categories ordered by parent_id, then by cat_id. You would then take the result set and build a multi-dimensional array from it. You could then loop through this array much as you currently do in order to output the categories.
While this is better from a DB access standpoint, it would also consume more memory as you need to keep this larger array in memory. So it really is a trade-off that you need to consider.
There is a lot to fix there, but I'll just address your question about reducing queries. I suggest getting rid of the WHERE clauses all together and use if statements within the while loop. Use external variables to hold all the results that match a particular condition, then echo them all at once after the loop. Something like this (I put a bunch of your stuff in variables for brevity)
//before loop
$firstInfoSet = '';
$secondInfoSet = '';
$thirdInfoSet = '';
//in while loop
if($parentID == NULL)
{
$firstInfoSet.= $yourFirstLineOfHtml;
}
if($active && $parentID == $catID) // good for query 2 and 3 as they are identical
{
$secondInfoSet.= $yourSecondLineOfHtml;
$thirdInfoSet.= $yourThirdLineOfHtml;
}
//after loop
echo $firstInfoSet . $secondInfoSet . $thirdInfoSet;
You can now make whatever kinds of groupings you want, easily modify them if need be, and put the results wherever you want.
--EDIT--
After better understanding the question...
$query = mysql_query("SELECT * FROM categories order by cat_id asc;", $hd);
$while ($row = mysql_fetch_assoc($query)){
if($row['parent_id'] == NULL){
//echo out your desired html from your first query
}
if($row['active'] && $row['parent_id']== $row['cat_id']){
//echo out your desired html from your 2nd and 3rd queries
}
}

MySQL query within foreach loop

I want to show all text messages from db where id=$e ($err is an array).
Inserted the query into the foreach loop, it works well but it does extra work (does query for every value of array).
Is there any other way to do it (i mean extract query from foreach loop)?
My code looks like this.
foreach ($err as $e)
{
$result = $db -> query("SELECT * from err_msgs WHERE id='$e'");
$row = $result -> fetch_array(MYSQLI_BOTH);
echo "<li><span>".$row[1]."</span></li>";
}
It is much more efficient to do this with implode() because it will only result in one database query.
if (!$result = $db->query("SELECT * FROM `err_msgs` WHERE `id`='".implode("' OR `id`='",$err)."'")) {
echo "Error during database query<br />\n";
// echo $db->error(); // Only uncomment this line in development environments. Don't show the error message to your users!
}
while ($row = $result->fetch_array(MYSQLI_BOTH)) {
echo "<li><span>".$row[1]."</span></li>\n";
}
Check the SQL IN clause.
Firstly, a bit of a lecture: embedding strings directly into your queries is going to cause you trouble at some point (SQL injection related trouble to be precise), try to avoid this if possible. Personally, I use the PDO PHP library which allows you to bind parameters instead of building up a string.
With regard to your question, I'm not sure I have understood. You say that it does extra work, do you mean that it returns the correct results but in an inefficient way? If so then this too can be addressed with PDO. Here's the idea.
Step 1: Prepare your statement, putting a placeholder where you currently have '$e'
Step 2: Loop through $err, in the body of the loop you will set the place holder to be the current value of $e
By doing this you not only address the SQL injection issue, you can potentially avoid the overhead of having to parse and optimise the query each time it is executed (although bear in mind that this may not be a significant overhead in your specific case).
Some actual code would look as follows:
// Assume that $dbdriver, $dbhost and $dbname have been initialised
// somewhere. For a mysql database, the value for $dbdriver should be
// "mysql".
$dsn = "$dbdriver:host=$dbhost;dbname=$dbname";
$dbh = new PDO($dsn, $dbuser, $dbpassword);
$qry = "SELECT * from err_msgs WHERE id = :e"
$sth = $dbh->prepare($qry);
foreach ($err as $e) {
$sth->bindParam(":e", $e);
$sth->execute();
$row = $sth->fetch();
// Prints out the *second* field of the record
// Note that $row is also an associative array so if we
// have a field called id, we could use $row["id"] to
// get its value
echo "<li><span>".$row[1]."</span></li>";
}
One final point, if you want to simply execute the query once, instead of executing it inside the loop, this is possible but again, may not yield any performance improvement. This could be achieved using the IN syntax. For example, if I'm interested in records with id in the set {5, 7, 21, 4, 76, 9}, I would do:
SELECT * from err_msgs WHERE id IN (5, 7, 21, 4, 76, 9)
I don't think there's a clean way to bind a list using PDO so you would use the loop to build up the string and then execute the query after the loop. Note that a query formulated in this way is unlikely to give you any noticable performance improvment but it really does depend on your specific circumstances and you'll just have to try it out.
You can do this much simpler by doing
$err_csv = implode("','",$err);
$sql = "SELECT FROM err_msgs WHERE id IN ('$err_csv')";
$result = $db -> query($sql);
while ($row = $result -> fetch_array(MYSQLI_BOTH))
{
echo "<li><span>".$row[1]."</span></li>";
}
That way you don't have to keep sending queries to the database.
Links:
http://php.net/manual/en/function.implode.php

Categories