right the problem is a smallish one but hope someone can help.
Basically we use memcache to cache some of our mysql queries and then store the results in an array for memcache. Then when the query runs again it grabs the array results from memcache and processes the results like normal.
So the code looks like this.
$query = "SELECT x,y,z FROM a WHERE b = 3";
$result = mysql_query_run($query,'memcache_name');
while($row = mysql_mem_fetch_array($result,'memcache_name')) {
//do processing
}
mysql_query_run basically just either runs the query or returns the array from memcache.
The mysql_mem_fetch_array either processes the results from mysql or transverses the array.
The transversing part uses this code.
if(is_array($result)) {
$return = current($result);
//get the current result - based on the internal pointer
next($result);//increment pointed
return $return;//return result
}
else {
//mysql result tab
//so get the array from the mysql_fetch_array
$array = mysql_fetch_array($result);
if(is_array($MEMCACHE_SERVER_RESULTS[$memcache])==false) {
//if there is no results then just set the results as array
$MEMCACHE_SERVER_RESULTS[$memcache] = array();
}
//push the array onto the end of the current array - from memcache
//if there are some results then push them on
if($single_row == 1) {
//only one row so just combine the 2 steps and store
array_push($MEMCACHE_SERVER_RESULTS[$memcache],$array);
$MEMCACHE_SERVER->set($memcache, $MEMCACHE_SERVER_RESULTS[$memcache],0,$memcache_time);
}
else if($array!==false) {
array_push($MEMCACHE_SERVER_RESULTS[$memcache],$array);
//and set it
}
else {
//set the memcache to the array that it has been making.
$MEMCACHE_SERVER->set($memcache, $MEMCACHE_SERVER_RESULTS[$memcache],0,$memcache_time);
}
//return array
return $array;
}
The problem is the current and next commands - in large arrays (which are very rare) it causes some hanging.
Currently we are in php version 5.1.6 and we are going to 5.3 will the problem be solved?
Or is there a better way to handle the array?
Thanks for your help.
Richard
in large arrays (which are very rare) it causes some hanging.
Easy. Just avoid storing large arrays in memcache.
If you do:
if (is_array($result)) {
$return = each($result); //get the current result and advance the array pointer
return $return['value']; //return result
} else // ...and so on
...is it any better?
Related
I'm executing a cursor. I have cutted off the code how the procedure is called and executed. This part is efficient.
At last I have a a not big cursor. I'm calling the procedure, which returns this cursor many times on the page and I need to create a multidimensional array from it. This array should look like like the following:
$ret = oci_execute($outrefc) ;
while ($row = #oci_fetch_array($outrefc))
{
foreach (array_keys($row) as $key)
{
$res[$i][$key] = $row[$key];
}
$i++;
}
Is there any way to make the upper snippet faster?
The multidimensional array should stay as it is. I only wonder if I could create it in any more efficient way.
Thank you!
In my PHP application. I am taking value from user and all these user values are stored in Array. And just for validation. I am comparing user input value with my array. :-
<?php
// Current Code
$masterArray = array(......); // ..... represents some 60-100 different values.
foreach($_POST as $key => $value) {
if(in_array($value, $masterArray)) {
$insertQuery = $mysqli->query("INSERTION stuff or Updating Stuff");
} else {
echo "Are you tampering html-form-data ?";
}
}
?>
But this is so worthless code, as it takes quite good time in updating or insertion.
Is there any better function that is way faster to check if value in slave array exists in master array ?
From Slave Array i Mean => List / Array of User Input value.
From Master Array i mean => List of my array value stored in page.
Thanks
I think i got the better option with array_diff.
Please let me know if i am doing anything wrong in below before i put this code in production page:- Thanks a lot for your efforts #J.David Smith & #grossvogel
<?php
$masterArray = array(.......); // My Master Array List
$result = array_diff($_POST['checkBox'], $masterArray);
if(count($result) > 0) {
// If they are trying to do some tampering , let them submit all again.
echo 'Something is not Right';
} else {
// If Person is genuine, no waiting just insert them all
$total = count($_POST['checkBox']);
$insertQuery = "INSERT into notes(user,quote) values ";
for($i=0;$i<=$total; $i++) {
array_push($values, "('someuser','".$mysqli->real_escape_string($_POST['checkBox'][$i])."')");
}
$finalQuery = $mysqli->query($insertQuery.implode(',', $values));
}
?>
Is my Code Better , I am testing it in localhost i don't see much of difference, I just want to know expert views if I am messing arround with something ? before i put this code in production page.
Update : This looks pretty better and faster than code in question.
Thanks
The only other way to do this is to use an associative array with your values as keys (well, you could custom-implement another storage container specifically for this, but that'd be overkill imo). Then, you can check with isset. For example:
$masterArray = array(....); // same thing, but with values as keys instead of values
foreach($_POST as $key => $value) {
if(isset($masterArray[$value])) {
// do stuff
} else {
// do stuff
}
}
I'm kind of curious what the point of doing this is anyway, especially given the statement printed by your echo call. There may be an even better way to accomplish your goal than this.
EDIT: Another method suggested by grossvogel: loop over $masterArray instead of $_POST. If you expect $_POST to be a large set of data consistently (ie most of the time people will select 50+ items), this could be faster. Hashing is already very fast, so you'll have to benchmark it on your code in order to make a decision.
$masterArray = array(...); // either style of definition will work; i'll use yours for simplicity
foreach($masterArray as $value) {
if(isset($_POST[$value])) {
// do stuff
}
}
this is the PHP code i have:
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
while ($row2 = mysql_fetch_object($query2)) {
echo "%".$row2->id."%";
}
}
I want it to output for example: *1*%1%%2%%3%%4%*2*%1%%2%%3%%4%*3*%1%%2%%3%%4%
But what this loop outputs is: *1*%1%%2%%3%%4%*2**3*
(It only outputs the $row2 values in the first loop of $row1.
How can I fix this? Thanks.
A few things to note about mysql_fetch_object(). From the PHP document:
Warning: This extension is deprecated as of PHP 5.5.0
Please note above.
returns an object with properties that correspond to the fetched row and moves the internal data pointer ahead.
Please note what I bolded.
The $result object (in your code this would be $query2) is an iterative object that has a pointer pointing to the current item.
Current Item
|
v
[1][2][3][4]
When your first loop hits your second loop, it iterates over the whole thing, such that at the end, the object now looks something like this:
Current Item
|
v
[1][2][3][4]
For each iteration of the first loop, after the first time, the mysql_fetch_object() function basically goes like this:
mysql_fetch_object() ~
1. Get the next time
2. Uh, there are no more objects because we're at item [4]. Return done.
So, how do you get it to work? You could simply save the results into an array and then iterate over that array or you can reset the pointer with mysql_data_seek() (which is also deprecated as of 5.5).
To reset the data pointer, it would be something like this:
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
while ($row2 = mysql_fetch_object($query2)) {
echo "%".$row2->id."%";
}
// put the result pointer back to the front
mysql_data_seek($query2, 0)
}
Note1, This SO question/answer helped me find the function to use to reset the pointer.
Note, the downside is that you're calling a function that's creating an object, which creates processing overhead every time it runs.
The other option would be save the results into an array and just loop through the array every time:
$secondary_result = array();
while ($row2 = mysql_fetch_object($query2)) {
$secondary_result[] = $row2;
}
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
foreach($secondary_result as $row2) {
echo "%".$row2->id."%";
}
}
Note, this method will be creating extra memory usage of storing the objects in an array, but it would save on CPU processing as you're not re-creating the objects over and over again, as well as calling a function.
If you just print output, you can consider just saving the result first. No matter now many times you loop over $secondary_result, the final result will always be the same (as per your code, the first loop shows no signs of being directly influencing the second result).
In that case, this makes much more sense
$buffer = '';
while ($row2 = mysql_fetch_object($query2)) {
$buffer .= "%".$row2->id."%";
}
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
echo $buffer;
}
but I really don't know why you'd do that. If you're doing a nested loop, usually it's because the result of the first loop is affecting the second loop.
But I hope that helps!
Cheers!
EDIT
Per #Blazemonger's comment about looking ahead, the PDO equivalent would be: MySqli:Fetch-Object
When you have a result object from using the PDO function, you would loop like this:
while($row1 = $query1->fetch_object()) {
echo "*".$row1->id."*";
while ($row2 = $query1->fetch_object()) {
echo "%".$row2->id."%";
}
// put the result pointer back to the front
$query2->data_seek(0);
}
The above example shows both the fetch Object and pointer reset versions of MySqli.
The problem is that once you iterate fully through $query2, that's the end of your results. The next time through your $row1 loop, you're still at the end of $query2 and have no results left. Try using mysql_data_seek to go back to the start of your results:
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
mysql_data_seek($query2, 0);
while ($row2 = mysql_fetch_object($query2)) {
echo "%".$row2->id."%";
}
}
if you really need to repeat your second query data many times, get it into array first, and loop over this array as many times as you need.
First of all: The mysql_* functions are deprecated and will be removed in PHP 5.5. Consider using mysqli or PDO instead.
That being said; back to your question:
Each result set contains an internal pointer to one of the records in the result set. Initially, this pointer points to the first record, and is advanced with each call to mysql_fetch_object.
After your first inner loop, the internal pointer of the $query2 result set will already be at the end of the list, so subsequent calls to mysql_fetch_object will only return FALSE.
If your inner query depends on values from $row1, you will need to re-execute the second query within your outer loop. Otherwise, you can reset the result pointer with mysql_data_seek.
Perhaps you're not getting anything when you call $row2 = mysql_fetch_object($query2) which would give you the output you're getting.
After the first loop there are no more results for query2 to return. So the while is false in each additional loop. You would want to reset the query with mysqli_data_seek or storing all the data in a separate array and looping through that instead.
Please also note:
Per the documentation http://us2.php.net/manual/en/function.mysql-fetch-object.php
The mysql extension is deprecated as of PHP 5.5.0, and will be removed
in the future. Instead, the MySQLi or PDO_MySQL extension should be
used
I have a sequence of mysql query result resources stored in a array.
E.G array([0] => resource [1] => resource ...ect);
This code retrieves the first resource in the array:
$third_count = "0";
while ($user_result = mysql_fetch_array($user[$third_count])) {
print_r($user_result);
}
$third_count = $third_count +1;
I'm just stuck trying to find an if statement that'll loop though the array.
Something like: while ($third_count =< $second_count) is what I need, but it doesn't seem to work.
Where $second count is the number of elements in the array.
Thanks for pointers!
What you want to do is use a foreach loop to loop through that array of result resources. Counts will not matter then.
foreach($resourcearr as $res) {
while ($user_result = mysql_fetch_array($res)) {
print_r($user_result);
}
}
Why am I not able to get inside the while loop in the getCustomers() function?
$stores = $bl->getStoresForGuide($gID); //Returns 6 stores
$storelist = getStoreList($stores); //Generate the HTML for the store list
$brandlist = getCustomers($stores); //Generate the HTML for brand list
function getStoreList($stores)
{
while ($row = mysql_fetch_array($stores)) {
// Do stuff
}
//return result
}
function getCustomers($stores)
{
echo mysql_num_rows($stores); //Outputs 6
while ($row = mysql_fetch_array($stores)) {
echo "test "; // Outputs nothing
}
// Return some result
}
You're looping twice. The first time you loop, you get to the end, and the pointer isn't reset before you loop again.
If you're sure you want to do this, check out mysql_data_seek, and seek to the beginning of the result. Otherwise, I'd recommend just storing the results and iterating over the array.
You are calling getStoreList first, then by the time you call getCustomers, $stores has already had all its rows fetched.