Here is my simplified code:
$connexion = new PDO(SQL_DSN,SQL_USERNAME,SQL_PASSWORD);
$connexion2 = new PDO(SQL_DSN2,SQL_USERNAME2,SQL_PASSWORD2);
[...]
$sqlIndex = "SELECT index_key,index_platforms_code
FROM index
WHERE index_missions_id = :mission";
$initFiches = $connexion->prepare($sqlIndex);
$initFiches->bindParam(":mission" , $_GET['mission']);
$initFiches->execute();
try
{
while ($fiche = $initFiches->fetch(PDO::FETCH_ASSOC))
{
print_r($fiche);
foreach ($structure['champs'] as $masterChamp)
{
//$stmt = $connexion2->prepare($masterChamp['sql']);
}
}
}
catch (exception $e)
{
echo "error".$e->getMessage();
}
My output:
Array
(
[index_key] => 1
[index_platforms_code] => 1
)
Array
(
[index_key] => 2
[index_platforms_code] => 2
)
Array
(
[index_key] => 3
[index_platforms_code] => 3
)
Array
(
[index_key] => 4
[index_platforms_code] => 4
)
All Right, but if I uncomment this line
$stmt = $connexion2->prepare($masterChamp['sql']);
in the foreach, this line broke the while above and here is the new output:
Array
(
[index_key] => 1
[index_platforms_code] => 1
)
Someone have an idea?
Here's a solution that doesn't involve 2 connections and that's more optimized.
$connexion = new PDO(SQL_DSN,SQL_USERNAME,SQL_PASSWORD);
$sqlIndex = "SELECT index_key,index_platforms_code
FROM index
WHERE index_missions_id = :mission";
$initFiches = $connexion->prepare($sqlIndex);
$initFiches->bindParam(":mission" , $_GET['mission'], PDO::PARAM_STR);
$initFiches->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt = $connexion->prepare("SELECT ...."); // Prepare outside of the loop, you don't have to prepare it X times, once is enough.
if(sizeof($data))
{
foreach($data as $row)
{
// Do your statement binding / executing.
}
}
Alternatively, it seems you might be able to do this with table joining rather than issuing a query for each row you get from the 1st table. Since you haven't posted the structure, I guess there's no much helping it at the moment.
Related
I hope someone can help me with this puzzle!
I have this code:
<?php
$user = 'myuser';
$pass = 'mypass';
try{
$dbh = new PDO('mysql:host=localhost;dbname=mybase', $user, $pass);
foreach($dbh->query('SELECT title FROM ads_listing') as $title);
foreach($dbh->query('SELECT slug FROM ads_listing') as $slug){
print_r($slug);
print_r($title);
}
$dbh = null;
} catch (PDOException $e){
print "ERROR!:" . $e->getMessage() . "<br/>";
die();
}
?>
It display:
Array ( [slug] => laptop-dell-e6420-in-good-condition-tj304mkn910a8 [0] => laptop-dell-e6420-in-good-condition-tj304mkn910a8 ) 1Array ( [title] => VW POLO Comfortline [0] => VW POLO Comfortline ) 1Array ( [slug] => vw-polo-comfortline-rf839h9c9d065 [0] => vw-polo-comfortline-rf839h9c9d065 ) 1Array ( [title] => VW POLO Comfortline [0] => VW POLO Comfortline )
The goal is to display from my table 10 random titles as an URL with the slug like: VW POLO Comfortline, Laptop dell e6420 in good condition,.
How can I do it please?
You just need to use LIMIT and RAND() in your query like:
SELECT title, slug FROM ads_listing ORDER BY RAND() LIMIT 10
then use this query and function fetch_assoc() to have the result in associative array type:
<?php
$query = "SELECT title, slug FROM ads_listing ORDER BY RAND() LIMIT 10";
$result = $connection -> query($query);
while($row = $result -> fetch_assoc()){
// you can use $row which has been read from table randomly
...
}
?>
in the previous code, $connection is the connection which has been got from PDO class. Obviously, you do not have to use exactly like what I wrote, but I suggest to you use one.
There are quite a few things going on here from a puristic point of view, but I think there are two things that are preventing you from solving this:
You don't fetch your data in a single query
You don't loop your data in a single loop
Going along with the assumption that $dbh->query() returns an associative array, you could do the following:
$user = 'myuser';
$pass = 'mypass';
try{
$dbh = new PDO('mysql:host=localhost;dbname=mybase', $user, $pass);
} catch (PDOException $e){
print "ERROR!:" . $e->getMessage() . "<br/>";
die();
}
$ads = $dbh->query('SELECT title, slug FROM ads_listing');
foreach ($ads as $ad) {
$title = $ad['title'];
$slug = $ad['slug'];
}
I'm trying to add an <hr> tag between lines when a new name is encountered.
$conn = new mysqli("localhost", "root", "", "test");
$rs = $conn->query("SELECT * FROM usuarios");
$info = [];
$i = 0;
while($rows = $rs->fetch_array()) {
$info[$i]["pass"] = $rows["pass"];
$info[$i]["name"] = $rows["name_real"];
$i++;
}
// I want to print a line just after the last duplicated value
for($i = 0; $i < count($info) - 1; $i++) {
if($info[$i]["name"] !== $info[$i +1]["name"] && // some duplicate condition) {
$info[$i]["line"] = "<hr>";
};
}
This is the structure of my info array build from the resultset.
Array
(
[0] => Array
(
[pass] => 12
[name] => Martin
)
[1] => Array
(
[pass] => 20
[name] => Martin
)
[2] => Array
(
[pass] => 2
[name] => Martin
)
[3] => Array
(
[pass] => 2
[name] => Alberto
)
)
My desired result would be something like:
<p>Martin<p>
<p>Martin<p>
<p>Martin<p>
<hr>
<p>Alberto<p>
If you don't care what the duplicate names are or how many duplicates exist, and you just want to see whether or not there are any, it looks like it could be simpler code than some of the possible duplicate answers.
Get the names
$names = array_column($array, 'name');
Then check if the full list of names is equal to the unique list.
$has_duplicates = $names != array_unique($names);
Disclaimer: This answer looks odd now. It was provided for Revision 1 of the question. I seem to have misunderstood the question somewhat, and then Revision 2 transformed it to the extent that this answer no longer applies at all. Still, I think it's a useful way to do the thing that it seemed was trying to be done at first.
This solution would be handy:
$result = array();
$names = array_count_values(array_column($source, 'name'));
foreach($names as $key=>$val) {
$result[$key] = ($val == 1 ? false : true);
}
This can be achieved with just one loop. First, use your mysqli query to order the resultset by name_real. (If you are only going to use name_real, you can change the SELECT clause to reflect this. I have shown this in the commented query.) Then write a condition that checks for a new/unique name_real -- if so, echo <hr>.
Code: (Demo)
//$rs = $conn->query("SELECT `name_real` FROM usuarios ORDER BY `name_real`;");
$rs=[
['pass'=>2,'name_real'=>'Alberto'],
['pass'=>12,'name_real'=>'Martin'],
['pass'=>20,'name_real'=>'Martin'],
['pass'=>2,'name_real'=>'Martin']
];
$prev=NULL;
//while($rows = $rs->fetch_array()) {
foreach($rs as $rows){
if($prev && $rows['name_real']!=$prev){ // if not first iteration, and new name_real
echo "<hr>";
}
echo "<p>{$rows['name_real']}</p>";
$prev=$rows['name_real']; // preserve this value for next iteration's check
}
Output:
<p>Alberto</p>
<hr>
<p>Martin</p>
<p>Martin</p>
<p>Martin</p>
This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 5 years ago.
I have a need to generate a MySQL query dynamically, and values of specific types may or may not appear in specific column types. Here is a case for a query generated for two x values and one y value, each of which must be present in either of respective sets of columns (please to not read it too close, since the query itself has been tested extensively and works alright if the proper parameters are inserted manually):
SELECT
*
FROM
TABLE
WHERE
(
/*start of block x0 */
(
(columm_x0 = ':value_type1_index1')
OR (column_x1 = ':value_type1_index1')
OR (column_x2 = ':value_type1_index1')
OR (column_x3 = ':value_type1_index1')
OR (column_x4 = ':value_type1_index1')
)
/* end of block 0*/
/*start of block x1 */
OR (
(columm_x0 = ':value_type1_index2')
OR (column_x1 = ':value_type1_index2')
OR (column_x2 = ':value_type1_index2')
OR (column_x3 = ':value_type1_index2')
OR (column_x4 = ':value_type1_index2')
)
/*end of block x1*/
/*start of block y1*/
AND (
(columm_y0 = ':value_type2_index1')
OR (column_y1 = ':value_type2_index1')
OR (column_y2 = ':value_type2_index1')
OR (column_y3 = ':value_type2_index1')
OR (column_y4 = ':value_type2_index1')
) /*end of block y1*/
)
This whole query is supplied to $query variable.
So each time we must search for values in all specific columns no matter what. The parameters themselves are supplied as array:
$values = Array ( [type1] => Array ( [0] => value1 [1] => value2 )[type2] => Array ( [0] => value3 ))
My PDO looks like the following:
try {
$connect = new PDO("mysql:host=".$db['server'].";dbname=".$db['db'], $db['mysql_login'], $db['mysql_pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt=$connect->prepare($query);
foreach ($values as $type => $typevalue){
foreach ($typevalue as $element => $elementvalue){
$parameter = ":value_{$type}_index{$element}";
$stmt->bindValue($parameter, $elementvalue, PDO::PARAM_STR);//i think here is the problem!
echo "<br>$parameter = $elementvalue<br>"; //shows exactly correct parameter and value
}
}
if ($stmt->execute() AND $stmt->rowCount() > 0){
echo "success";
//do some stuff
} else {
echo "false".' '. $stmt->rowCount() . '<br>';
$stmt->debugDumpParams();
}
}
catch(PDOException $e) {
echo $e->getMessage();
}
The resulting query using pdo always returns 0 rows although the parameters replaced with values manually result in success.
As i said above, i don't think that bindValue() method allows variables in parameter.
Any help would be appreciated.
All i had to do was to remove the quotes around the parameters in query so this is correct:
(column_x1 = :value_type1_index2)
and this is NOT correct:
(column_x1 = ':value_type1_index2')
Im using this DOMXpath query to retrieve some columns from another page.
$html = file_get_contents("http://localhost:8888/stockPrices.php");
libxml_use_internal_errors(true);
$doc = new \DOMDocument();
if($doc->loadHTML($html))
{
$result = new \DOMDocument();
$result->formatOutput = true;
$table = $result->appendChild($result->createElement("table"));
$thead = $table->appendChild($result->createElement("thead"));
$tbody = $table->appendChild($result->createElement("tbody"));
$table->setAttribute('class', 'table table-hover');
$xpath = new \DOMXPath($doc);
$newRow = $thead->appendChild($result->createElement("tr"));
foreach($xpath->query("//table[#id='kurstabell']/thead/tr/th[position()=2 or position()=3 or position()=8 or position()=9 or position()=10]") as $header)
{
$newRow->appendChild($result->createElement("th", trim($header->nodeValue)));
}
foreach($xpath->query("//table[#id='kurstabell']/tbody/tr") as $row)
{
$newRow = $tbody->appendChild($result->createElement("tr"));
foreach($xpath->query("./td[position()=2 or position()=3 or position()=8 or position()=9 or position()=10]", $row) as $cell)
{
$newRow->appendChild($result->createElement("td", trim(htmlentities($cell->nodeValue))));
}
}
echo $result->saveXML($result->documentElement);
}
This generates four columns, aktier, senaste, högst, lägst and omsatt. But i dont know how to insert this to a MySQL table. Im thinking to first generate a array of the result, like:
Array
(
[1] => stdClass Object
(
[aktie] => AAK AB
[senaste] => 634,50
[högst] => 638,50
[lägst] => 622,50
[omsatt] => 32 094 048
)
[2] => stdClass Object
(
[aktie] => ABB Ltd
[senaste] => 162,80
[högst] => 163,30
[lägst] => 161,90
[omsatt] => 167 481 268
)
(you get the hang of it..)
)
According to this image:
And then loop the array into the table. Something like this?
$sql = "INSERT INTO stock_list (`aktie`, `senaste`, `högst`, `lägst`, `omsatt`, `timestamp`) VALUES
(:aktie, :senaste, :högst, :lägst, :omsatt)";
$query = $database->prepare($sql);
foreach($data as $stock){
$query->execute(array(':aktie' => $stock->stock,
':senaste' => $stock->prevclose,
':högst' => $stock->high,
':lägst' => $stock->low,
':omsatt' => $stock->volume
));
}
My question:
How do i populate the array with data?
How do i loop the result in a mysql query?
Don't know if this is a work around. But it is currently doing what I'm asking for.
// build query...
$sql = "INSERT INTO stocks";
// columns to insert into...
$sql .="(`name`, `closing`, `high`, `low`, `turn`, `timestamp`)";
// implode values of $array...
// notice array_chunk, this functions splits a big array into multi.
$str = NULL;
foreach (array_chunk($a, 5) as $row) {
$str .= '("'. implode('","',$row).'",NOW()),';
}
// Remove last ',' (comma) from string
// We added commas in the previous step
$str = rtrim($str,',');
$sql .= 'VALUES '. $str ;
// execute query...
$app = new Connection();
$query = $app->getConnection()->prepare($sql);
$query->execute();
if ($query->rowCount() <= 0) {
echo "Something went wrong.";
return false;
}
return true;
My guess is that what you really want is something along the lines of:
$query = 'INSERT INTO stock_list
(`aktie`, `senaste`, `högst`, `lägst`, `omsatt`, `timestamp`)
VALUES
(:aktie, :senaste, :högst, :lägst, :omsatt, NOW())';
$stmt = $app->getConnection()->prepare($query);
foreach ($data as $stock) {
$stmt->execute(
[
':aktie' => $stock->aktie,
':senaste' => $stock->senaste,
':högst' => $stock->{'högst'},
':lägst' => $stock->{'lägst'},
':omsatt' => $stock->omsatt,
]
);
$stmt->closeCursor();//might be required depending on DB driver, not for MySQL, though
}
Note that I call NOW() in the query string, and I don't bind that SQL function call to the parameters I execute the prepared statement with. All in all though, a timestamp field is best set by the DB itself (with a DEFAULT CURRENT_TIMESTAMP in the field definition). Then you can just leave the timestamp field out of your INSERT query, and it'll be set correctly for you.
I've also changed the way you're using the objects stock. From the var_dump I can see the properties aren't called stock, high, low and all that. The problem is, some of these property names (lägst for example) are a bit dodgy. You'll probably have to access those using a string, which can be done, like I did, by writing $objVar->{'property name as string'}.
If I were you, though, I'd look into ways of changing what $data actually looks like, and change the property names if at all possible.
Problem: Even though my $settings array has values (int) in them, MySQL writes NULL into the table both when the value is 0 and 2.
For reference, each index in the $settings array is an array of [0] = max and [1] = min.
public function updateAdaptiveArmour($gameid, $shipid, $settings){
foreach ($settings as $key => $value){
debug::log($key." ".$value[0]." ".$value[1]);
//just to show the contents
// [561103190304f][2015-10-04 12:44:41] particle 4 2
// [56110319035b3][2015-10-04 12:44:41] laser 0 0
// [56110319035b3][2015-10-04 12:44:41] molecular 0 0
}
try {
if ($stmt = $this->connection->prepare(
"UPDATE
tac_adaptivearmour
SET
particlealloc = ?,
laseralloc = ?,
molecularalloc = ?
WHERE
gameid = ?
AND shipid = ?
"
))
{
$stmt->bind_param('iiiii', $settings[0][1], $settings[1][1], $settings[2][1], $gameid, $shipid);
$stmt->execute();
$stmt->close();
}
}
catch(Exception $e) {
throw $e;
}
}
Ideally, for this example, I would want to UPDATE to 2 / 0 / 0 instead of null / null / null.
Your array is populated as follows:
$settings = [
'particle' => [4, 2],
'laser' => [0, 0],
'molecular' => [0, 0]
];
I hope that answers the question without needing to further explain it.
It will be fixed as follows:
$stmt->bind_param('iiiii',
$settings['particle'][1],
$settings['laser'][1],
$settings['molecular'][1],
$gameid,
$shipid
);