Thread: mysql_fetch_?
cdc


What's the best mysql_fetch_ function to use for performance?

I'm talking about:

mysql_fetch_object
mysql_fetch_row
mysql_fetch_array
mysql_fetch_assoc

Does it matter?

grandpa

1st post!!

i dont know, i always use mysql_fetch_array.
never tried mysql_fetch_assoc & mysql_fetch_object

perkiset

fetch_row and fetch_array are clearly the most often used.

fetch_row is the lowest impact because it maps the fields you SELECTed to numeric indicies only - so if you do somthing like select count('x') from contacts you are certain that row[0] will be the one you want. fetch_array also returns the numeric indicies (little known item) but also creates array entries that are name-indexed to the field you selected. so select fname, lname from contacts would give you array entries of 0, 1, fname and lname.

I do not use the other two because a) I don't do objects in mysql and b) I have never tried the assoc, although I see that it is used all over the SMF code and that triggered me to give it a whirl. Given that it is in this codebase, it certainly must be stable and reliable.

/p

cdc

Well, it sounds like we have all the bases covered because I use fetch_object almost exclusively. I'm not sure why, but it probably has something to do with me

learn

 ing 

PHP

  after using Java for 5 years and latching on to anything OO.

quote
I don't do objects in mysql


Just to clarify, using fetch_object doesn't imply that you do anything different in your database. After the fetch you get an object back and you can access your data like so:


$obj = mysql_fetch_object($result);
$id = $obj->id;
$name = $obj->name;


I was wondering if there was a de facto way of doing this and why...

vsloathe

I love it when you use Latin vernacular CDC.

Caligula

This is interesting...  the only one I can ever get to work is mysql_fetch_array... I have tried all the others and nothing seems to do the job I need other than fetch_array plus if you use MYSQL_BOTH as the result type it should return an associative array as well as  a numeric array... so you can kind of catch both and use what you need...

thedarkness

quote author=Caligula link=topic=132.msg726#msg726 date=1177723991

This is interesting...  the only one I can ever get to work is mysql_fetch_array...


Do a print_r or var_dump on the result dude, that way you can see exactly what you are dealing with.

Cheers,
td

Caligula

Oh so thats what the damn 'var_dump' is used for....

php

 

.net

  describes it as var_dump — Dumps information about a variable  ..... I just automatically assumed it did the same job as 'unset()'  Thanks Bro

Karlo

I am usually usign fetch_assoc because the fetch_object doesn't work for non-ascii values.
No, not that I'd name a column "Karlo's links".
It's a just-in-case thing...

K.

vsloathe

Late to the party as usual, but I usually use fetch_array with ASSOC because it's easy for me to remember the column names (in most instances), being first and foremost (and by all formal training) a database developer.

On a side note, I just got the

php

 _mssql lib to actually work which is really nice, because I didn't want to have to port all my data to MySQL and I REALLY didn't want to have to brush up on my

ASP

 

.NET

  when I'm pretty good at

PHP

 . Though I'll always respect MySQL and use it frequently, I really like abilities I have now because of the tools I have in MS's management studio (which was of course already paid for, so why not use it?) and a language that I'm fairly familiar with. Using Transact-SQL, stored procedures, and

PHP

  to do some pretty funky stuff now.

perkiset

Glad to know you're there... between you and NBs I know who to go to if I have trouble with a new job I just got - all

PHP

  and MSSQL

/p

vsloathe

Perks I need some help with something, it should be pretty straightforward. I will have to talk to you later via IM about it. I basically made a little web page where the user can select fields from a dropdown and then conditions (= or CONTAINS), and that affects the SQL query. It's not really that bulletproof, very susceptible to injection which I'm not worried about at this point because the users who will be using it don't know anything about databases and they are all local in this office (won't be a widely deployed app). Anyway, I want to have an "OR" and "AND" button which will add another row of fields and conditions, but I don't know how I should do it. I figure I can do it pretty easily in

javascript

 , but then all the switch statements in the

PHP

  are going to start getting a little hairy. I'm sure you've done stuff way more advanced so I'm looking for guidance.

perkiset

I C U...

vsloathe

As a followup, I basically made an incrementer with the

javascript

  so that the user could have a limitless number of ANDs and ORs added on, then in my

PHP

  I do a for loop where I did $i<(count($_POST)/4) since there are about 4 variables to each of the conditions to formulate my SQL query.

Then I did something cool that someone somewhere might be interested in, I gave the user a button "download to excel spreadsheet". It looks like this:


<?

php

 
echo'
<form action="download.

php

 " method="POST">
<input type="hidden" name="query" value="'.urlencode($query).'">
<input type="submit" value="Applauseownload as Spreadsheet">
</form>
';


Then download.

php

  looks like this:


<?

php

 
require_once("datagrid.

php

 ");
function db_connect()
{
$myServer = "SERVER";
$myUser = "USER";
$myPass = "PASS";
$myDB = "ApplauseB";

$s = @mssql_connect($myServer, $myUser, $myPass)
or die("Couldn't connect to SQL Server on $myServer");

$d = @mssql_select_db($myDB, $s)
or die("Couldn't open database $myDB");
}
db_connect();
$query=urldecode($_POST['query']);
$result = mssql_query($query);

header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=Extraction.xls");
header("Pragma: no-cache");
header("Expires: 0");
DataGrid($result); 
?>


It works pretty sexily. The only hangup is that it's not truly in Excel format so Excel bitches the first time you open it up, but it's just being a pain because it knows how to read it and you can re-save it pro

perl

 y formatted.

vsloathe

Here is the solution that I came up with, with all the sensitive information changed.

If anyone has suggestions as far as hacking on some security, I'd appreciate it.


<?

php

 
/****************************************************
Query.

php

  - This page formulates SQL queries from user input.
It gives the user a very fine grain of control over the queries and
allows him or her to see all the columns in a particular table in your
database, so I would only use it in a trusted environment. The design
could definitely stand some improvement, but I don't claim to be a
designer.
-Drew
8/10/2007
****************************************************/
require_once("functions.

php

 ");//All functions contained in functions.

php

 .
?>
<HTML>
<head>
<script type="text/

javascript

 ">
var i=0;
function addAND()
{
i=i+1;
  var newrow;
  newrow='<TABLE border="0"><TR><TH colspan="3">AND<TR><TH>Column:<TH>Condition:<TH>Query:<TR><TD><select name="field'+i+'"><?printfields();?></select><TD><select name="condition'+i+'"><option value ="=">=</option><option value ="CONTAINS">CONTAINS</option><option value ="!=">NOT =</option><option value ="NOT CONTAIN">ApplauseOES NOT CONTAIN</option></select><TD><input type="text" name="q'+i+'"><input type="hidden" name="andor'+i+'" value="AND"></TABLE>';
document.getElementById('issues').innerHTML+=newrow;
}
function addOR()
{
i=i+1;
  var newrow;
  newrow='<TABLE border="0"><TR><TH colspan="3">OR<TR><TH>Column:<TH>Condition:<TH>Query:<TR><TD><select name="field'+i+'"><?printfields();?></select><TD><select name="condition'+i+'"><option value ="=">=</option><option value ="CONTAINS">CONTAINS</option><option value ="!=">NOT =</option><option value ="NOT CONTAIN">ApplauseOES NOT CONTAIN</option></select><TD><input type="text" name="q'+i+'"><input type="hidden" name="andor'+i+'" value="OR"></TABLE>';
document.getElementById('issues').innerHTML+=newrow;
}
</script>
</head>
<body>
<div id="formWrapper">
<div id="formDiv">
<form action="<?$_SERVER['

php

  self'];?>" method="POST">
<div><input id="submitButton" type="submit" value="Submit Query"/>&nbsp;<input type="button" value="Add AND Condition" onclick="addAND();"/>&nbsp;<input type="button" value="Add OR Condition" onclick="addOR();"/></div>
<div id="issues"><TABLE border="0"><TR><TH>Column:<TH>Condition:<TH>Query:<TH>Sort By:<TR><TD><select name="field0"><?printfields();?></select><TD><select name="condition0"><option value ="=">=</option><option value ="CONTAINS">CONTAINS</option><option value ="!=">NOT =</option><option value ="NOT CONTAIN">ApplauseOES NOT CONTAIN</option></select><TD><input type="text" name="q0"><TD><select name="order0"><?printfields()?></select></TABLE></div>
</form>
</div>
</div>
</body>
</html>
</HTML>

<?

php

 
$query="SELECT * ";//Begin constructing query.
$query.="FROM TABLE ";

if(isset($_POST['q0']))//If first POST variable is set
{
for($i=0;$i<(count($_POST)/4);$i++)//Determine how many additional ANDs or ORs we have by looping through.
{
if(isset($_POST['q'.$i]))//If Nth POST variable is set.
{
$q=$_POST['q'.$i];//assign values.
$field=$_POST['field'.$i];
$condition=$_POST['condition'.$i];
$mod="WHERE";//Default value of modifier is WHERE. Changes to AND or OR for either of those.

switch($condition)//Determine operand condition.
{
case "=":
$cond="=";
$newq="'".$q."'";
$q=$newq;
break;
case "CONTAINS";
$cond="LIKE";
$newq="'%".$q."%'";
$q=$newq;
break;
case "!=";
$cond="=";
$newfield="NOT ".$field;
$field=$newfield;
$newq="'".$q."'";
$q=$newq;
break;
case "NOT CONTAIN";
$newfield="NOT ".$field;
$field=$newfield;
$cond="LIKE";
$newq="'%".$q."%'";
$q=$newq;
break;

}
if(isset($_POST['andor'.$i]))//If it's a secondary condition ORed or ANDed on.
{
$andor=$_POST['andor'.$i];
switch($andor)//Determine operand.
{
case "AND":
$mod="AND";
break;
case "OR":
$mod="OR";
break;
}
}

$query.="$mod $field ";//Construct latter part of query.
$query.="$cond $q ";
}

}
$order=$_POST['order0'];//Determine what to order on.
$query.="ORDER BY $order";

db_connect();//Connect to database.

$result = mssql_query($query);//Execute Query
$numrows = mssql_num_rows($result);

echo("$numrows rows returned.<br /><br />");//Number of rows returned.
echo'
<form action="download.

php

 " method="POST">
<input type="hidden" name="query" value="'.urlencode($query).'">
<input type="submit" value="Applauseownload as Spreadsheet">
</form>
';//Button to download as Excel Spreadsheet.
DataGrid($result);//Display results in data grid.
}
?>


Here is the functions.

php

 :


<?

php

 
function db_connect()
{
$myServer = "SERVER";
$myUser = "USER";
$myPass = "PASS";
$myDB = "ApplauseB";

$s = @mssql_connect($myServer, $myUser, $myPass)
or die("Couldn't connect to SQL Server on $myServer");

$d = @mssql_select_db($myDB, $s)
or die("Couldn't open database $myDB");
}

function printfields()
{
db_connect();
$qq=mssql_query("SELECT * FROM TABLE");
$num=mssql_num_fields($qq);

for($i=0;$i<=$num;$i++)
{
echo('<option value ="['.@$field=mssql_field_name($qq,$i).']">'.@$field=mssql_field_name($qq,$i).'</option>');
}
}

function DataGrid($result)
{
if(mssql_num_rows($result)==0)//If the query did not return any rows...
{
echo"No data to display.";
}
else
{
echo('<TABLE border="2">');//Make a table.
$num=mssql_num_fields($result);
echo('<TR>');
for($i=0;$i<=$num;$i++)//Print each field name as a column header.
{
echo('<TH>'.@$field=mssql_field_name($result,$i));
//The @ supresses the error when we run out of field names.
}
while($row = mssql_fetch_array($result,MSSQL_ASSOC))
{
echo('<TR>');//Begin the table row.
foreach($row as $a)
{
if($a != '' && $a != 'REF!' && $a != '0' && $a != ' ')
//My data has a bunch of junk in it, you can remove this part if yours is clean.
{
echo('<TD>'.$a);//Echo each piece of data as a <TD> element.
}
else
{
echo('<TD>-');//Easier on the eyes than having all that gibberish in the table.
}
}
}

}

}
?>

perkiset

Nice work VS... and thanks for the code!

vsloathe

Yeah the only issue is that if I add another condition via the AND or OR buttons, the stuff I filled out above it goes away. Problem with adding to innerHTML, I know and I remember you talking about using the DOM tree or something Perk, can you give me some help with that? All I care about is making it so the contents of the previous form fields doesn't get wiped when I add new ones via the buttons.

perkiset

Couple ways to do it:

First off, you could do the whole thing in JS at the client and only shoot the new rules up to the server and retrieve the new SQL query. That'd be how I'd do it (or similar, as I showed you) In this way, the DOM/Form elements that contain the data entered by the surfer become your variables - I know it's a little weird to think about, but why clutter the namespace if the DOM is hanging onto everything you need? getElementById() is of course the start of it, but I have many forms where there is an unknown number of user entries  - like the one I showed you, the user can click the "+" button and add or the "-" button and remove any number of criteria as they choose... so I <as the coder> do not know the outside constraints of how many items they might be using.

My solution: getElementsByTagName() and DOM walking functions.

Let's say that I have have a table that contains <> rows of data. In each of the locations where the user can put data in there is an input. They are always in the same order, because the row construction comes from a template of my design. The table's ID is "inputTable"

So:

var theTable = getElementById('inputTable');
var theRows = theTable.getElementsByTagName('TR');
var max = theRows.length;
for (vari=0; i<max; i++)
{
var inputs = theRows<>.getElementsByTagName('input');
// ... at this point, inputs[0..n] are pointers to the inputs on each row
}


As you can see, it is not that difficult at all to contain [an unknown amount] of data elements in a page and use the page itself for storage.

Another option is to use the localStorage class in the JS repository. This will allow you to store lots of cookie data easily on the local system Then you'd use simple JS to open the cookie file and re-populate the entry fields with everything they had in the last iteration of the page. That methodology is rather simple - it's pretty much a persistent variable structure, so you could store any kind of data that makes you happy so that you know *how* to repopulate the input fields.

Hope that helps, postback if you need more clarification,
/p

vsloathe

I think I get it. When you talk about "ApplauseOM Walking", you're basically saying to walk through the existing form and grab all the values in the inputs right? That way when the user creates a new row, I can repopulate the existing ones each time?

EDIT: Ok I'm pretty thick when it comes to JS, how do I repopulate the elements in each row?

perkiset

Zactly.

Since I do virtually everything like this in an

AJAX

  way rather than posting forms, before I "send it all up" I walk the DOM, collect all the values and put them into params for my

AJAX

  call and dispatch it. Since nothng really happens to the form (we aren't moving to another page) there's no need for me to store much in cookies or persistently... the page is still there even though the request as been thrown at the server.

I also use this sort of DOM walking for results if I need to - I am more likely to ship back HTML to be put into a container with innerHTML than I am XML and interpret it... so the result gets dropped into a DIV and then if I need something I'll walk it. It's pretty handy once you get the hang of it.

vsloathe

Ok I'll post it here:

I'm pretty thick when it comes to JS, how do I repopulate the elements in each row when banging another input onto the end?

perkiset

Right -

Well, if you do it in an

AJAX

  way then you won't have to do anything because the page hasn't moved.

But if you do it in a POST kind of way, then you'll need to work to two different modes: loading a saved query from the server and modifying an existing query at the client. Both of these can be looped into a single process though, IMO.

There are of course two different ways to do this - either reload the fields at

PHP

  time or reload them from persistent values at JS time. If you do it at

PHP

  time, then you simply take the $_POST values and push them into HTML. Each block of information needs to be uniquely named so that you can get it from the POST variables. I suggest that you name the fields something like fname_1 - where fname is First Name and _1 is a counter - you'd then go _2, _3 etc for all the surfer rows. Then you'd do somthing like this:


$i = 1;
while ($_POST["fname_$i"])
{
// do something with the first name value...

// Now place it back into HTML for output...
$output[] = <<<HTML
<tr>
<td><input type="text" value="{$_POST["fname_$i"]}"></td>
</tr>
HTML;
}
$outputStr = impode(chr(10), $output);


That'd give you both access to the value and create your HTML that will contain the same value for the way back out to the surfer.

The other way of doing it would be to reload existing data from cookies into the fields. I'll only cover this briefly since there are also a bazillion ways to do this.

Assuming though that you were using the localStorage() class, the code might look something like this:

<script>
var storage = new localStorage('mydata');
storage.fileName = 'mydata';
var max = storage.retrieveItem('numberOfFields');
for (var i=1; i<=max; i++)
{
document.getElementById('fname_' + i).value = storage.retrieveItem('fname_' + i);
}
</script>


Note that this little fragment is just the tiniest hint of what all is possible - you'd have a lot more work to do to create a robust and stable UI.

Using the code from the "walk" example above, storing the fields is not that much more difficult (out of laziness I have switched to a zero-indexed counter so this code is not directly applicable to the code above, but you get the idea...)

storage = new localStorage();
storage.fileName = 'mydata';
function prePost()
{
var max = 0;
var theTable = document.getElementById('editTable');
var theRows = theTable.getElementsByTagName('TR');
for (var i=0; i<theRows.length; i++)
{
storage.storeItem('fname_' + i, document.getElementById('fname_' + i));
max++;
}
storage.storeItem('numberOfRows', max);
}


You're jumping into a cool, but somewhat complicated place. Just sayin.

/p

vsloathe

Thanks for the tips Perkomatic. I'll be in the office tomorrow and probably going to try to implement what you've suggested there. Was on vacation all last week in Maine. No, I didn't see any Bushes. I was north of them.


Perkiset's Place Home   Politics @ Perkiset's