I'm having trouble with some PHP since yesterday, looked through the web and had the stupid feeling that I'm missing something important.
Using mysql_fetch_object usually, tried it with mysql_fetch_array though (did not help). Here's the part of the code which gives me an headache:
public static function get_datacenter_by_id($id) {
$result = mysql_query("SELECT COUNT(rack.id) AS Racks, COUNT(device.id) AS Devices, COUNT(card.id) AS Cards, COUNT(port.id) AS Ports
FROM datacenter, rack, device, card, port, location, building
WHERE location.id = building.location_id AND
building.id = datacenter.building_id AND
datacenter.id = '.$id.' AND
rack.id = device.rack_id AND
device.id = card.device_id AND
(card.id = port.card_id1 OR
card.id = port.card_id2)") or die ("Error in query: ".mysql_error());
$array = array();
while($row = mysql_fetch_object($result)) {
$array[] = array($row->Racks, $row->Devices, $row->Cards, $row->Ports);
}
return $array;
}
$array is used in another .php file, but using print_r $array already shows you, that the array stays empty (0). I'm quite sure that the error appears in this block of code, could "COUNT (x) AS y" be at fault?
PS: The MySQL Query works, tested it via Workbench before. I'd appreciate some good adivce! :-)
Have a nice day!
Isn't this as simple as:
$result = mysql_query("SELECT COUNT(rack.id) AS Racks, COUNT(device.id) AS Devices, COUNT(card.id) AS Cards, COUNT(port.id) AS Ports
FROM datacenter, rack, device, card, port, location, building
WHERE location.id = building.location_id AND
building.id = datacenter.building_id AND
datacenter.id = '" . $id . "' AND
rack.id = device.rack_id AND
device.id = card.device_id AND
(card.id = port.card_id1 OR
card.id = port.card_id2)") or die ("Error in query: ".mysql_error());
Note the modification from '.$id.' to '" . $id . "'. Your query is looking for a data centre ID of '.$id.'.
Instead of using it like this
while($row = mysql_fetch_object($result)) {
$array[] = array($row->Racks, $row->Devices, $row->Cards, $row->Ports);
}
You should do this
$row = mysql_fetch_object($result)
$array[] = $row->Racks;
$array[] = $row->Devices;
$array[] = $row->Cards;
Because you are fetching 1 record and using it in while is causing problem
Related
I'm new to PHP and MySQL. I need to fill an array and I want to change the field names and I can't achieve it.
My code:
$querystr = "SELECT DISTINCT descr_bien,ubicacion,marca,modelo,ano,DescrMoneda,valor FROM bienes,Moneda WHERE bienes.IdMoneda = Moneda.IdMoneda AND bienes.Idpropuesta = '" . addslashes($Idpropuesta) . "'";
$result3 = mysql_query($querystr,$dbConn);
while($hrow = mysql_fetch_assoc($result3)){
$descr_bien = $grow['descr_bien'];
$ubicacion = $grow['ubicacion'];
$marca = $grow['marca'];
$modelo = $grow['modelo'];
$ano = $grow['ano'];
$DescrMoneda = $grow['DescrMoneda'];
$valor = number_format($grow['valor'],2,",",".");
$data = array(array('Descripción'=>$descr_bien,'ubicacion'=>$ubicacion,'marca'=>$marca,'modelo'=>$modelo,'Año'=>$ano,'DescrMoneda'=>$DescrMoneda,'valor'=>$valor),array($hrow));
}
$pdf->ezTable($data,$cols,'Bienes:',array('gridlines'=> EZ_GRIDLINE_DEFAULT,'shadeHeadingCol'=>array(0.6,0.6,0.5),'showBgCol'=>1,'width'=>500,'cols'=>array('valor'=>array('justification'=>'right'))));
Okay first of all I am going to assume you have managed to set up $dcConn to get your database connection. If not go look at http://php.net/manual/en/function.mysql-connect.php
Next your while statement is storing each value in $hrow but you seem to be assigning everything to grow.
Your next issue is that $data will be overwritten for every row in your result.
From what I understand you will be wanting something along the lines of
$querystr = "SELECT DISTINCT descr_bien,ubicacion,marca,modelo,ano,DescrMoneda,valor FROM bienes,Moneda WHERE bienes.IdMoneda = Moneda.IdMoneda AND bienes.Idpropuesta = '" . addslashes($Idpropuesta) . "'";
$result3 = mysql_query($querystr,$dbConn);
while($hrow = mysql_fetch_assoc($result3)){
$descr_bien = $hrow['descr_bien'];
$ubicacion = $hrow['ubicacion'];
$marca = $hrow['marca'];
$modelo = $hrow['modelo'];
$ano = $hrow['ano'];
$DescrMoneda = $hrow['DescrMoneda'];
$valor = number_format($grow['valor'],2,",",".");
$data[] = array('Descripción'=>$descr_bien,'ubicacion'=>$ubicacion,'marca'=>$marca,'modelo'=>$modelo,'Año'=>$ano,'DescrMoneda'=>$DescrMoneda,'valor'=>$valor));
}
I do not know about the last line at all so left it out.
One other suggestion that using the PDO library to access the mysql database would usually be a better idea unless this all that the php will ever need to do.
I hope this helps
apologize firstly for my questionable coding in php/mysql however this is all self taught (possibly not best practice)
All my code seems to work , however when the results are written to the page any $dxcall that is not in the $qrzdata database gets filled with the last result all other data displays fine. I have tried changing the like $dxcall to = $dxcall. I have also tried combining the fetch arrays too incase my issues was there too. But clearly my code does not know how to handle where there is not data match in the qrzdata database and to move on.
$frqry is the main data, all the other mysql_query's be it the $squares and $qrzdata are matching what comes from $frqry. Hope this makes sense !!
Here is my code
$frqry = mysql_query("select * from spots where freq between '69900' and '70300' ORDER BY datetime desc limit 30");
While ($r0 = mysql_fetch_array($frqry))
{
$freq = $r0["freq"];
$dxcall = $r0["dxcall"];
$datetime = $r0["datetime"];
$comments = $r0["comments"];
$spotter = $r0["spotter"];
$dt = date('d-m-y H:i ', $datetime);
$qra = $r0["loc"];
$squares = mysql_query("select * from squares where callsign like '$dxcall' limit 1");
while ($r1 = mysql_fetch_array($squares))
{
$qra = $r1["loc"];
}
$qrzdata = mysql_query("select * from qrzdata where callsign = '".$dxcall."' limit 1");
While ($r2 = mysql_fetch_array($qrzdata))
{
$country = $r2["country"];
$firstname = $r2["firstname"];
$city = $r2["city"];
}
Any help is greatly appreciated. Thank you.
You need to learn about the power of the JOIN ;)
Your whole code could be rewritten in one single query :
disclaimer: not tested, but you certainly get the idea
SELECT * FROM spots
JOIN squares ON (squares.callsign = spots.dxcall) -- this comes in stead of your first inner loop
JOIN qrzdata ON (qrzdata.callsign = spots.dxcall) -- this is your second loop
WHERE freq BETWEEN 69900 AND 70300 -- remove quotes, you are dealing with integers, not strings (hopefully)
You have to reset your vars!
While ($r0 = mysql_fetch_array($frqry))
{
$qra = '';
$country = '';
$firstname = '';
$city = '';
or you will allways get the last value
I need some help please. I have this from my database:
SELECT DISTINCT
iwi.item Item, ppd.item_des Des, iwi.qty_on_hand QOH, iwi.qty_allocated QA,
iwi.qty_on_order QOO, iwi.min_qty Minimum, MAX(ppm.expected_date)Exp_Date
FROM inv_warehouse_items iwi, pur_po_master ppm, pur_po_detail ppd)
WHERE IWI.CO = '100'
AND iwi.item_key = ppd.item_key
AND ppm.po_key = ppd.po_key
AND iwi.warehouse = '01'
AND iwi.item IN ('BXHP335',
'BXHP435',
'BXHP535',
'BXHP644',
'BXHP743',
'BXHP965',
'BXHP10741',
'BXHP10748',
'BXHP1253',
'BXHP1257',
'BXHP121210',
'BXHP151410',
'BXHP16114',
'BXHP181411',
'BXHP241612',
'BX1195',
'BX6636',
'BXHP201512',
'BXHP1949',
'BXHP2015',
'BXHP201515',
'BXHP351011',
'BXHP241814',
'BXHP2257',
'BXHP1824')
GROUP BY iwi.item, iwi.qty_on_hand, iwi.qty_allocated, iwi.qty_on_order,
iwi.min_qty, ppd.item_des
ORDER BY iwi.item"
And I need it to print out with php.
May be like this
$query = "...";
$result = $mysqli_query($db, $query);
while($row = mysqli_fetch_assoc($result)) {
print_r($row);
}
for ($i=0; $i<$count; $i++) {
$appid = $chk[$i];
include "dbconnect.php";
$selectquery = mysql_query("SELECT * FROM regform_admin WHERE tid = '$appid'");
$fetch = mysql_fetch_array($selectquery);
$tid = $fetch['tid']; $username = $fetch['username']; $c_month = $fetch['month']; $c_day =$fetch['day']; $c_year = $fetch['year'];
$c_month2 = $fetch['month2']; $c_day2 =$fetch['day2']; $c_year2 = $fetch['year2'];
$pickup = "".$c_month."/".$c_day."/".$c_year."";
$return = "".$c_month2."/".$c_day2."/".$c_year2."";
$pickuploc = "".$fetch['pickupret']." "." ".$fetch['speclocation']."";
$desti = "".$fetch['destination']." "." ".$fetch['location']."";
$vehicle1 = $fetch['vehicle1'];
$datesent = date("n j, Y; G:i"); ;
$rand = rand(98765432,23456789);
include "vehicledbconnect.php";
$vquery = mysql_query("SELECT * FROM vehicletbl WHERE vehicle = '$vehicle1'");
$getvquery = mysql_fetch_array($vquery);
$maxcars = $getvquery['maxcars'];
$carsleft = $getvquery['carsleft'];
if ($carsleft == 0) {
echo '
<script language="JavaScript">
alert("Cannot move reservation to Pending for payment status. No available vehicles left for this reservation.");
</script>';
echo "$vehicle1";
}
Hi guys my problem here is that the $vehicle is not returning its values if it is inserted in a database query ($vquery = mysql_query("SELECT * FROM vehicletbl WHERE vehicle = '$vehicle1'");) but if it is echoed, it return its value. The logic here is that it will select all the values from vehicletbl wherein the value of any values in 'vehicle' column will be equal to the $vehicle1. Thanks for the help!
You've got ZERO error handling on your queries. Try adding some debugging to the query calls:
$result = mysql_query(...) or die(mysql_error());
The rest of the code is ugly, but looks "ok", so start looking at WHY you're not getting anything back from the queries.
Never ever assume a query succeeds.
try this to debug :
$sql = "SELECT * FROM vehicletbl WHERE vehicle = '" . $vehicle1 . "'";
$vquery = mysql_query($sql) or die(mysql_error() . "\n<br>$sql");
thats what i do to find errors in my sql.
Noob programmer ? Here are some things to know :
for ($i=0; $i<$count; $i++) {
$appid = $chk[$i];
// Replaced By ...
foreach($chk as $appid){
http://php.net/manual/en/control-structures.foreach.php
// Include the file before the loop ! You're including 20 times your file, but you just need to do it once ! Another thing to know:
include_once("dbconnect.php");
http://php.net/manual/en/function.include-once.php
$desti = "".$fetch['destination']." "." ".$fetch['location']."";
// WHY ?? Isn't that easier to do this ?
$desti = $fetch['destination']." ".$fetch['location'];
And security :
// Don't forget to escape your variables before putting it in mysql queries
$appid = mysql_real_escape_string($appid);
$selectquery = mysql_query("SELECT * FROM regform_admin WHERE tid = '$appid'");
Best way to defend against mysql injection and cross site scripting
There are other remarks, but try to improve those points first !
Long before I knew anything - not that I know much even now - I desgined a web app in php which inserted data in my mysql database after running the values through htmlentities(). I eventually came to my senses and removed this step and stuck it in the output rather than input and went on my merry way.
However I've since had to revisit some of this old data and unfortunately I have an issue, when it's displayed on the screen I'm getting values displayed which are effectively htmlentitied twice.
So, is there a mysql or phpmyadmin way of changing all the older, affected rows back into their relevant characters or will I have to write a script to read each row, decode and update all 17 million rows in 12 tables?
EDIT:
Thanks for the help everyone, I wrote my own answer down below with some code in, it's not pretty but it worked on the test data earlier so barring someone pointing out a glaring error in my code while I'm in bed I'll be running it on a backup DB tomorrow and then on the live one if that works out alright.
I ended up using this, not pretty, but I'm tired, it's 2am and it did its job! (Edit: on test data)
$tables = array('users', 'users_more', 'users_extra', 'forum_posts', 'posts_edits', 'forum_threads', 'orders', 'product_comments', 'products', 'favourites', 'blocked', 'notes');
foreach($tables as $table)
{
$sql = "SELECT * FROM {$table} WHERE data_date_ts < '{$encode_cutoff}'";
$rows = $database->query($sql);
while($row = mysql_fetch_assoc($rows))
{
$new = array();
foreach($row as $key => $data)
{
$new[$key] = $database->escape_value(html_entity_decode($data, ENT_QUOTES, 'UTF-8'));
}
array_shift($new);
$new_string = "";
$i = 0;
foreach($new as $new_key => $new_data)
{
if($i > 0) { $new_string.= ", "; }
$new_string.= $new_key . "='" . $new_data . "'";
$i++;
}
$sql = "UPDATE {$table} SET " . $new_string . " WHERE id='" . $row['id'] . "'";
$database->query($sql);
// plus some code to check that all out
}
}
Since PHP was the method of encoding, you'll want to use it to decode. You can use html_entity_decode to convert them back to their original characters. Gotta loop!
Just be careful not to decode rows that don't need it. Not sure how you'll determine that.
I think writing a php script is good thing to do in this situation. You can use, as Dave said, the html_entity_decode() function to convert your texts back.
Try your script on a table with few entries first. This will make you save a lot of testing time. Of course, remember to backup your table(s) before running the php script.
I'm afraid there is no shorter possibility. The computation for millions of rows remains quite expensive, no matter how you convert the datasets back. So go for a php script... it's the easiest way
This is my bullet proof version. It iterates over all Tables and String columns in a database, determines primary key(s) and performs updates.
It is intended to run the php-file from command line to get progress information.
<?php
$DBC = new mysqli("localhost", "user", "dbpass", "dbname");
$DBC->set_charset("utf8");
$tables = $DBC->query("SHOW FULL TABLES WHERE Table_type='BASE TABLE'");
while($table = $tables->fetch_array()) {
$table = $table[0];
$columns = $DBC->query("DESCRIBE `{$table}`");
$textFields = array();
$primaryKeys = array();
while($column = $columns->fetch_assoc()) {
// check for char, varchar, text, mediumtext and so on
if ($column["Key"] == "PRI") {
$primaryKeys[] = $column['Field'];
} else if (strpos( $column["Type"], "char") !== false || strpos($column["Type"], "text") !== false ) {
$textFields[] = $column['Field'];
}
}
if (!count($primaryKeys)) {
echo "Cannot convert table without primary key: '$table'\n";
continue;
}
foreach ($textFields as $textField) {
$sql = "SELECT `".implode("`,`", $primaryKeys)."`,`$textField` from `$table` WHERE `$textField` like '%&%'";
$candidates = $DBC->query($sql);
$tmp = $DBC->query("SELECT FOUND_ROWS()");
$rowCount = $tmp->fetch_array()[0];
$tmp->free();
echo "Updating $rowCount in $table.$textField\n";
$count=0;
while($candidate = $candidates->fetch_assoc()) {
$oldValue = $candidate[$textField];
$newValue = html_entity_decode($candidate[$textField], ENT_QUOTES | ENT_XML1, 'UTF-8');
if ($oldValue != $newValue) {
$sql = "UPDATE `$table` SET `$textField` = '"
. $DBC->real_escape_string($newValue)
. "' WHERE ";
foreach ($primaryKeys as $pk) {
$sql .= "`$pk` = '" . $DBC->real_escape_string($candidate[$pk]) . "' AND ";
}
$sql .= "1";
$DBC->query($sql);
}
$count++;
echo "$count / $rowCount\r";
}
}
}
?>
cheers
Roland
It's a bit kludgy but I think the mass update is the only way to go...
$Query = "SELECT row_id, html_entitied_column FROM table";
$result = mysql_query($Query, $connection);
while($row = mysql_fetch_array($result)){
$updatedValue = html_entity_decode($row['html_entitied_column']);
$Query = "UPDATE table SET html_entitied_column = '" . $updatedValue . "' ";
$Query .= "WHERE row_id = " . $row['row_id'];
mysql_query($Query, $connection);
}
This is simplified, no error handling etc.
Not sure what the processing time would be on millions of rows so you might need to break it up into chunks to avoid script timeouts.
I had the exact same problem. Since I had multiple clients running the application in production, I wanted to avoid running a PHP script to clean the database for every one of them.
I came up with a solution that is far from perfect, but does the job painlessly.
Track all the spots in your code where you use htmlentities() before inserting data, and remove that.
Change your "display data as HTML" method to something like this :
return html_entity_decode(htmlentities($chaine, ENT_NOQUOTES), ENT_NOQUOTES);
The undo-redo process is kind of ridiculous, but it does the job. And your database will slowly clean itself everytime users update the incorrect data.