I have a table containing user id with left node and right node (Both are which user id). I am trying to create a function to count all the right nodes and total nodes of a particular user id in PHP.
The Code I have written till now which is always returning 0 :
function allcount($id) //Function to calculate all children count
{
$sqlz = "SELECT * FROM user_transaction_details WHERE user_id = '$id'";
$execsql = mysqli_query($conn,$sqlz);
$array = mysqli_fetch_array($execsql);
echo $sqlz;
(array_count_values($array));
$count = 0;
echo $array['l_node'];
if(!empty($array['l_node']))
{
$count += allcount($array['l_node']) +1;
}
if(!empty($array['r_node']))
{
$count += allcount($array['r_node']) +1;
}
return $count;
}
Here is the table structure :
Table Structure
Can anybody please help.
You need to pass $conn as an argument or declare it as global inside the function, because otherwise it is not available inside the function.
Related
We have a PHP script that loops through many XML / CSV files from different websites. Right now we manage to build a good XML / CSV parser script.
The PHP script we wrote is looping though some BIG XML or CSV files. In these XML or CVS files contains Barcodes from different products.
Right now before the script starts I fill an array with the Product ID + Barcode from the MySQL like this:
function Barcodes_Array() {
$sql = "SELECT ProductId, Barcode FROM Products WHERE (Barcode <> '') ";
$res = mysql_query($sql);
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][] = $rijen;
}
}
Each time we loop through the XML (or CSV) files we have to check if the Barcode exists in the array and return the Product ID.
For searching in the function:
$ProductId = SearchBarcodeProduct($EanNr, 'Barcode');
And yet the function:
function SearchBarcodeProduct($elem, $field)
{
$top = sizeof($GLOBALS['arrBarcodes']) - 1;
$bottom = 0;
$ProductId = 0;
while($bottom <= $top)
{
if($GLOBALS['arrBarcodes'][$bottom][$field] == $elem) {
return $GLOBALS['arrBarcodes'][$bottom]['ProductId'];
}
else {
if (is_array($GLOBALS['arrBarcodes'][$bottom][$field])) {
if (in_multiarray($elem, ($GLOBALS['arrBarcodes'][$bottom][$field]))) {
return $GLOBALS['arrBarcodes'][$bottom]['ProductId'];
}
}
}
$bottom++;
}
return $ProductId;
}
We fill in the array because it took forever each time we ask the MySQL Products Table.
My Question is now:
It still takes a VERY long time each time looping through the array of the barcodes. Is there a faster way for any other solutions maybe a different way then a array?
Can someone help please i am working like weeks on this stupid :) thing!
Why do you need 2 functions?
Try just one
function itemBarcode($id) {
$id = intval($id);
$sql = "SELECT ProductId, Barcode FROM Products WHERE ProductId = $id Barcode <> '') ";
$res = mysql_query($sql);
if ($row = mysql_fetch_assoc($res)) {
return $row['barcode'];
} else {
return 0;
}
}
Update if you need to search by barcode you can create another function:
function itemProduct($barcode) {
$sql = "SELECT ProductId, Barcode FROM Products WHERE Barcode = $barcode ";
$res = mysql_query($sql);
if ($row = mysql_fetch_assoc($res)) {
return $row['ProductId'];
} else {
return 0;
}
}
Sounds like you are missing an index on your Barcode column in your database.. A single row lookup using a presumably unique single indexed column should be blisteringly fast.
CREATE INDEX Barcode_Index ON Products (Barcode)
Then simply:
SELECT ProductId FROM Products WHERE Barcode = *INPUT*
You could also make the index UNIQUE if you NULL the Barcode where they currently = '' if there are more than one of these.
Another option is keying the array you have with the Barcode:
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][$rijen['Barcode']] = $rijen;
}
or even just:
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][$rijen['Barcode']] = $rijen['ProductId'];
}
Then you can do a straight look up:
$ProductId = isset($GLOBALS['arrBarcodes'][$Barcode])
?$GLOBALS['arrBarcodes'][$Barcode]['ProductId']
:0;
or:
$ProductId = isset($GLOBALS['arrBarcodes'][$Barcode])
?$GLOBALS['arrBarcodes'][$Barcode]
:0;
N.B Please read the warnings in the comments about use of $GLOBALS and mysql_query.
If you need it, store the barcodes array in an object or variable instead.
PDO is pretty handy, and I think it can also key your returned array for you on fetch.
Hi I'm currently querying from a database base user ids for a contest, However I want to avoid choosing duplicates in my results_array, this function getrandomspecies receives a array_result, this array results iterates 7 times. How test that I don't put duplicates in my results_array? I have gotten several duplicates.
function getrandomspecies($array_result){
//database connection
$dbn = adodbConnect();
foreach($array_result as $possible){
//query the results
$querys= "select * from taxonomic_units where tsn = $possible";
$resultss = $dbn -> Execute($querys);
while($rowss=$resultss->FetchRow()){
$id = $rowss['tsn']; //there ID
$ranksss = $rowss['rank_id']; //ranking id, I choose 220 and 230
if($ranksss == 220 || $ranksss == 230){
$prelimary_array[] = $id;
}
}
//grab random index
$index = array_rand($prelimary_array,1);
//put result id into a variable
$newspecies = $prelimary_array[$index];
//put that variable in an array
$results_array[] = $newspecies; //there is 7 newspecies/winners at the end, I dont want duplicates
}
return $results_array;
}
MySQL should be the following :
select distinct tsn, rank_id from taxonomic_units where tsn = $possible
But you should ideally use prepared statements.
what about this? You may do it with one query:
$querys= "select DISTINCT tsn from taxonomic_units where tsn IN (".implode(",",$array_result).") AND rank_id IN (220,230) ORDER BY RAND() LIMIT 7 ";
Loop your result array and if it does not exists add it. If you end up with less than 7, do your big loop again.
replace this line :
$results_array[] = $newspecies;
by:
$loop_1_more_time=0;
if (isset($results_array)){
foreach($results_array as $result){
if ($result == $new_specie){
$loop_1_more_time=1;
}
}
}
if ($loop_1_more_time == 0){
$results_array[] = $newspecies;
}
//there, if $loop_1_more_time equals 1, start again. To start again and be sure you have seven instead of 6 or less, You could replace your big first "foreach" loop with a "for" loop that depends of the count() of the $array_result, and the $array_result would be array_result[$i] instead of $possible. $i would start at 0 and increment at each end of loop. It would not be incremented if $loop_1_more_time==1;.
Example :
for ($i = 0; $i < count($array_result); $i++) {
//stuff
//if ($loop_1_more_time=1;) { $i--; }
}
Why don't you try shuffling the array, and then picking the first X numbers?
That way, rather than having to check the results array for duplicates, it will never come up in the first place
I've tried looking for a solution in other questions asked before (as always), but I can't seem to wrap my head around this.
See, I want to get a number of unique IDs (in random order) from one table and store them in an array without echoing them. Then I want to use that array variable in a loop, so that I can increment the key with every pass, and set another variable to that array variable. Confusing? I think looking at the code will make it more clear.
The problem is I can't seem to store the values that I've queried into an array for later use in the code. I pasted the pertinent part of the code with my spots of trouble indicated by comment /* */ tags.
Any help is appreciated.
<?php
include ('parse_functions.php');
if ($fetch['use_rand']=='yes')
{ $loop = 5;
$concept = $fetch['concept'];
$countRandom = "SELECT exID FROM examples WHERE concept='$concept' ORDER BY RAND()";
$askForRandom = mysql_query($countRandom) or die(mysql_error());
/* HERE I NEED TO STORE RANDOM KEYS (exID) INTO AN ARRAY */ }
else
{ if (!empty($fetch['ex5'])) { $loop = 5; }
elseif (!empty($fetch['ex4'])) { $loop = 4; }
elseif (!empty($fetch['ex3'])) { $loop = 3; }
elseif (!empty($fetch['ex2'])) { $loop = 2; }
elseif (!empty($fetch['ex1'])) { $loop = 1; }
else { $loop = 0; }
}
if ($loop!==0)
{
echo '<div id="examples">' . "\n";
echo '<table class="showExample" cellspacing="0" cellpadding="0" border="0" align="center">' . "\n";
$turns = 1;
do {
if ($fetch['use_rand']=='no')
{ $exID = $fetch['ex'.$turns.'']; }
else
{ $exID = /* THIS IS WHERE I WILL USE "RANDOM VARIABLE" */; }
$askExamples = "SELECT * FROM examples WHERE exID='$exID'";
$getExamples = mysql_query($askExamples) or die(mysql_error());
$sortExamples = mysql_fetch_assoc($getExamples);
echo '<tr>' . "\n";
// ...and so on
If all you need to do is store the info in an array, here's an easy way about it.
/* code
to open
db here
*/
/* assuming you have a value for $concept */
$countRandom = "SELECT exID FROM examples WHERE concept='$concept' ORDER BY RAND()";
$askForRandom = mysql_query($countRandom) or die(mysql_error());
$Element = 0; //Array elements start at ZERO. So this is to intialise it.
while ($Fields = mysql_fetch_array($askforRandom)) //As long as there are records, get them.
{
//Records are retrieved one at a time. So store each one's exID in the array element
$Data[$Element] = $Fields["exID"];
//Soon after storing one, increment the value of the $Element variable so it is ready for the next one.
$Element++
}
/* now you have the data in the array. So you can do what you like with it. */
hope it helps
NOTE: when reading the array, make sure you put the condition to check that your counter is LESS than $Element. This is because after reading the last record, $Element is incremented by one. Hope this is clear.
Why not just grab all the right information in one query from the start along the lines of something like this:
select
a.exID,
examples.someField,
examples.someOtherField
from
examples
join
(
SELECT
exID
FROM
examples
WHERE
concept='$concept'
ORDER BY
RAND()
limit 5
) a
on a.exID=examples.exID
Then you just just pop them into an array (or better yet object) that has all the pertinent information in one row each time.
I have a Joomla 1.5 site. I have articles in my site with different "status". What I'm trying to do is "count" and show how many articles have for example "status = 1"(expired) or "status = 3"(blocked) or "status = 2"(active) etc..
Here is the statuses in PhpMyAdmin - http://awesomescreenshot.com/07a8ijz75
Here is what I wrote, but it ALWAYS gives me same result - 1
<?php echo count($this->row->status==1) ?>
Did I miss something?
Thanks
Use the SQL count function.
select count(*) from articles where status = 1;
Use your DB! If you are sorting, counting, etc, data from a database in PHP code you're doing it wrong.
If you want all statuses, do something like:
select status, count(*) from articles group by status;
The count function in PHP counts all the elements in an array, and in your example you passed it a boolean value. As a result count doesn't know what to do with it, and so it returns -1, which isn't a valid count.
My PHP is really rusty (I haven't used it in a looong time), but here are two possible ways to accomplish what you want:
1. Use a function map/reduce style
<?php
$row[0]->status = 1;
$row[1]->status = 2;
$row[2]->status = 1;
$row[3]->status = 3;
$row[4]->status = 1;
// Count the number of statuses that are equal to 1
echo array_reduce(array_map(function($x) {
return $x->status == 1 ? 1: 0;
}, $row), function($x, $y) {return $x + $y;});
You'll have to replace the $row variable with $this->row, obviously. The code is essentially working in two steps. The inner part:
array_map(function($x) {
return $x->status == 1 ? 1: 0;
}, $row)
Creates a list where every status that's equal to 1 becomes a 1 and everything else becomes a 0. So you have an array of "array(1, 0, 1, 0, 1)". The out part of the code:
array_reduce( ... , function($x, $y) {return $x + $y;});
Takes the new array as the first argument and sums it all up by passing in the first two values of the array into the function, and then each following value and the result of the last function call. As a result all the values get summed, and you have a proper count of the matching values.
2. Use a simple procedural style
<?php
$row[0]->status = 1;
$row[1]->status = 2;
$row[2]->status = 1;
$row[3]->status = 3;
$row[4]->status = 1;
// Do it again, but in a procedural style
$num_1_statuses = 0;
foreach ($row as $r) {
if ($r->status == 1) {
$num_1_statuses++;
}
}
echo $num_1_statuses;
This should be really straightforward, it just has a variable that gets incremented whenever a row's status matches.
Hi I am creating a system that processes and ID and a UID, The UID we are generating randomly but I am a little stuck, I need to always generate a UID that does not currently exist in the db as the field is a unique field used on the front end so as not to expose the real ID.
So to recap, I am trying to generate a unique id that does not currently exist in the DB the part I haven't got working is the cross checking in the db so it sometimes will give a number that already exists in the db even though it shouldn't thanks in advance.
This is my code so far:
function uniqueID($table)
{
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$possible = '1234567890';
$code = '';
$characters = mt_rand(7,14);
$i = 0;
while($i < $characters)
{
$code .= substr($possible, mt_rand(0, strlen($possible)-1), 1);
$i++;
}
$result = $db->query('
SELECT uniqueID
FROM '.$table.'
WHERE uniqueID = "'.$code.'"
LIMIT 1
');
$totalRows = $result->num_rows;
if(!$result)
{
return $db->error;
}
else
{
if($totalRows > 0)
{
return uniqueID($table);
}
else
{
return $code;
}
}
}
http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_uuid
To generate unic UID you can use time, i think it was a very small chanse that records will be added in the same second, with two random data.
write some function which return it to you like that
function generate_uid(){
return md5(mktime()."-".rand()."-".rand());
}
In PHP there's a function called uniqid()
http://php.net/manual/en/function.uniqid.php
I could talk about generating ids, like the others did, but this is not your question.
Your query seems fine. If it returns 0 rows but you seem to find the code in the database, then most likely it only looks the same, but actually isn't. It could be padded by whitespace.
One way to solve this is by selecting the last row of your user database and have your script to check for the id field (you can achieve this by performing a select ordering by ID in descendent mode) then you can use that info for randomize numbers greater than that ID.
EDIT
$result = $db->query('
SELECT uniqueID
FROM '.$table.'
');
$already_in_database = array();
while ($row = mysql_fetch_array($result)){
$already_in_database[] = $row['UID'];
}
$new = rand(0,$some_max_value);
while(in_array($new,$already_in_database)){
$new = rand(0,$some_max_value);
}
I figured out what the problem was already, As I mentioned to everyone the code generation was not the issue! The issue was that the cross check was not working correctly. So all I did was removed this loop
while($i < $characters)
{
$code .= substr($possible, mt_rand(0, strlen($possible)-1), 1);
$i++;
}
As this was causing my unique ID to end up wrong.