Why is my loop not incrementing? - php

I am trying to take a subset of an mysql statements results from an if statement, and if the last one in the sequence, apply appropriate code.
I want to set up two increments and then if($secondcount > $totalcount) do something else.
MySqlNUMRows won't work as it is a subset, neither will a where clause in this case, that I can see. Can anyone see the cause?
$counting = 0;
while($thisrow = mysqli_fetch_array($sqlchangenamesresult))
{
$change_name = $thisrow['change_name'];
#count the updating results
if(strstr($row['Content_lists'], $change_name) != FALSE)
{
$counting++;
}
$totalcount = $counting;
$secondcount = 0;
if(strstr($row['Content_lists'], $change_name) != FALSE)
{
if($secondcount > $totalcount)
{
echo '<br>' .$secondcount. '<br>' . $totalcount;
$sqlinsert .= $thisrow['change_name'];
$sqlinsert2 .= 'Yes';
$secondcount++;
}
else
{
echo '<br>' .$secondcount. '<br>' . $totalcount;
$sqlinsert .= $thisrow['change_name'] . ', ';
$sqlinsert2 .= 'Yes, ';
$secondcount++;
}
}

$secondcount is 0, so it cannot be larger than $totalcount.
note:
!= FALSE is incorrect
$totalcount always equals $counting. why have to variables?
$secondcount++; is in both branches.. move it out of the branch body.

Related

How to solve Oscommerce, Warning: sizeof(): Parameter must be an array or an object that implements Countable

I install the latest version of OSCommerce framework. in backend Categories/Products error shown like:
Warning: sizeof(): Parameter must be an array or an object that implements Countable in C:\xampp\htdocs\oscommerce\catalog\admin\includes\functions\general.php on line 93
I try to use is_array() and count() but still not working, below are the code
function tep_get_path($current_category_id = '') {
global $cPath_array;
if ($current_category_id == '') {
$cPath_new = implode('_', $cPath_array);
} else {
if (sizeof($cPath_array) == 0) {
$cPath_new = $current_category_id;
} else {
$cPath_new = '';
$last_category_query = tep_db_query("select parent_id from " . TABLE_CATEGORIES . " where
categories_id = '" . (int)$cPath_array[(sizeof($cPath_array)-1)] . "'");
$last_category = tep_db_fetch_array($last_category_query);
$current_category_query = tep_db_query("select parent_id from " . TABLE_CATEGORIES . " where
categories_id = '" . (int)$current_category_id . "'");
$current_category = tep_db_fetch_array($current_category_query);
if ($last_category['parent_id'] == $current_category['parent_id']) {
for ($i = 0, $n = sizeof($cPath_array) - 1; $i < $n; $i++) {
$cPath_new .= '_' . $cPath_array[$i];
}
} else {
for ($i = 0, $n = sizeof($cPath_array); $i < $n; $i++) {
$cPath_new .= '_' . $cPath_array[$i];
}
}
$cPath_new .= '_' . $current_category_id;
if (substr($cPath_new, 0, 1) == '_') {
$cPath_new = substr($cPath_new, 1);
}
}
}
return 'cPath=' . $cPath_new;
}
I added below code in the file just the line which was giving the error.
if ($cPath_array == null) {
$cPath_array = array();
}
It has resolved my error
sizeof is an alias of count.
count's behavior changed in Php 7.2.
count() will now yield a warning on invalid countable types passed to the array_or_countable parameter.
Possible causes:
var_dump(count([])); // OK
var_dump(count((object)[])); // Warning
var_dump(count(null)); // Warning
var_dump(count(false)); // Warning
var_dump(count(123)); // Warning
var_dump(count('123')); // Warning
Please check the data type of $cPath_array using var_dump. $cPath_array is implemented as array in the code but whats its actual value for which warning is generated.
Bad and Temporary solution:
Downgrade your Php version.
You could also use empty(). It checks if a variable is "falsy".
if (empty($cPath_array)) { }
Instead of
if (sizeof($cPath_array) == 0) { }

php array values not being pushed onto associative array

I wrote a javascript function which takes in a string and parses it as an associative array.
function getValues(string){
var array_values = new Array();
var pairs_array = string.split('\n');
if(pairs_array[0] == 'SUCCESS'){
window.success = true;
}
for(x=1; x< pairs_array.length; x++){
var parsedValue = '';
//console.log(pairs_array[x] + "<br>");
var pair = pairs_array[x].split('=');
//console.log(pair[1]);
var variable = pair[0];
if(pair[1]){
var value = pair[1];
for(i=0; i< value.length; i++){
var character = value.charAt(i);
if(character == '+'){
parsedValue = parsedValue + character.replace('+', ' ');
}else{
parsedValue = parsedValue + value.charAt(i);
}
}
array_values[variable] = decodeURIComponent(parsedValue);
}else{
array_values[variable] = '';
}
}
return array_values;
}
Then the function is called on the string window.name_value_pairs as follows
var array_callback = getValues(window.name_value_pairs);
for(x in array_callback){
console.log("call" + x + " " + array_callback[x]);
}
Works fine. Now i have been trying to write the function in php because i would prefer it on the server side but it is not working out. I'm not sure if the array values ar getting pushed onto the array because nothing gets returned. heres the php code i have tried:
Note: $results_values is a string
$result_values = $_REQUEST['result_values'];
echo "php array " . getValuesPhp($result_values);
function getValuesPhp($string){
$array_values = array();
$pairs_array = explode("\n",$string);
if($pairs_array[0] == 'SUCCESS'){
$success = true;
echo "TRUE";
}
for($x=1; $x< count($pairs_array); $x++){
$parsedValue = '';
$pair = explode("=",$pairs_array[$x]);
$variable = $pair[0];
if(isset($pair[1])){
$value = $pair[1];
for($i=0; $i< strlen($value); $i++){
$character = $value[$i];
//echo "char \n" . $character;
if(strpos($character, '+') !== false){
//echo "plus";
$parsedValue .= str_replace('+', ' ', $character);
}else{
//echo "hi2";
$parsedValue .= $value[$i];
}
}
echo "\n var " . $variable;
echo "\n parsed " . $parsedValue;
$array_values['" . $variable . "'] = $parsedValue;
//echo "arrayValues " . $array_values['" . $variable . "'];
//array_push($GLOBALS[$array_values]['" . $variable . "'], $parsedValue);
}else{
$array_values['" . $variable . "'] = '';
//array_push($GLOBALS[$array_values]['" . $variable . "'], '');
}
}
//echo "array payment stat" . $array_values['payment_status'];
return $array_values;
}
note: where it says $array_values['" . $variable . "'] this does print out the write result as it goes through the loop however it seems like the array elements are not being added to the array as nothing is returned at the end.
Thanks for any help
Sarah
Update:
#ChrisWillard I would like to return an associative array from the string. the string is in the format where each line is in the form key=value .. it is actually the string which comes back from a paypal pdt response. For example:
SUCCESS
mc_gross=3.00
protection_eligibility=Eligible
address_status=confirmed
item_number1=3
tax=0.00
item_number2=2
payer_id=VWCYB9FFJ
address_street=1+Main+Terrace
payment_date=14%3A26%3A14+May+22%2C+2014+PDT
payment_status=Completed
charset=windows-1252
address_zip=W12+4LQ
mc_shipping=0.00
mc_handling=0.00
first_name=Sam
address_country_code=GB
address_name=Sam+Monks
custom=
payer_status=verified
business=mon%40gmail.com
address_country=United+Kingdom
num_cart_items=2
mc_handling1=0.00
mc_handling2=0.00
address_city=Wolverhampton
payer_email=monks%40gmail.com
mc_shipping1=0.00
mc_shipping2=0.00
tax1=0.00
tax2=0.00
txn_id=3PX5572092U
payment_type=instant
last_name=Monks
address_state=West+Midlands
item_name1=Electro
receiver_email=mon%40gmail.com
item_name2=Dub
quantity1=1
quantity2=1
receiver_id=WHRPZLLP6
pending_reason=multi_currency
txn_type=cart
mc_gross_1=1.00
mc_currency=USD
mc_gross_2=2.00
residence_country=GB
transaction_subject=
payment_gross=3.00
thanks for all your answers and help. it was a combination of two things that caused it to not print.. firstly my silly syntax error (being just new at programming haha I wont go into the logic i had behind this but it did make sense to me at the time haha) $array_values['" . $variable . "'] = $parsedValue; changed to this:
$array_values[$variable] = $parsedValue;
it was also the line
echo "php array" . getValuesPhp($result_values); that caused it not to print.
when i changed this to
print_r(getValuesPhp($result_values)); it printed perfect thanks to #ChrisWillard for this. So here is my final code. A combination of #ChrisWillard answer and #Mark B and #Jdo answers. I also wanted to check first if pair[1] existed and go through each character of pair[1] changing any '+' to a space ' ' if it existed so that it could be read by the user. Now i have found the function to do this for me haha. I'm sure it is not new information for a lot of you but for anyone who doesn't know it is urldecode so you can see below ive commented out the loop that i did not need (going through the characters of the string changing the plus value) and instead ive written: $finished_array[$key] = urldecode($value); thanks for all your help.
$result_values = $_REQUEST['result_values'];
print_r(getValuesPhp($result_values));
function getValuesPhp($string){
$finished_array = array();
$pairs_array = explode("\n",$string);
if($pairs_array[0] == 'SUCCESS'){
$success = true;
//echo "TRUE";
}
for($x=1; $x< count($pairs_array); $x++){
$parsedValue = '';
$pair = explode("=",$pairs_array[$x]);
$key = $pair[0];
if(isset($pair[1])){
$value = $pair[1];
//for($i=0; $i< strlen($value); $i++){
//$character = $value[$i];
//if(strpos($character, '+') !== false){
//$parsedValue .= str_replace('+', ' ', $character);
//}else{
//$parsedValue .= $value[$i];
//}
//}
$finished_array[$key] = urldecode($value);
}else{
$finished_array[$key] = '';
}
}
return $finished_array;
}
This is totally non-sensical:
$array_values['" . $variable . "'] = $parsedValue;
You're literally using " . $variable . " as your array key - remember that '-quoted strings do NOT expand variables.
Why not just
$array_values[$variable] = $parsedValue
From what I can gather, this should get you what you need:
$result_values = $_REQUEST['result_values'];
print_r(getValuesPhp($result_values));
function getValuesPhp($string){
$finished_array = array();
$pairs_array = explode("\n",$string);
if($pairs_array[0] == 'SUCCESS'){
$success = true; ////Not sure what you're trying to do here
}
for($x=1; $x< count($pairs_array); $x++) {
$pair = explode("=",$pairs_array[$x]);
$key = $pair[0];
$value = $pair[1];
$finished_array[$key] = $value;
}
return $finished_array;
}

How To Change Numbers Based On Results

I have a follow up question on something I got help with here the other day (No Table Three Column Category Layout).
The script is as follows:
$res = mysql_query($query);
$system->check_mysql($res, $query, __LINE__, __FILE__);
$parent_node = mysql_fetch_assoc($res);
$id = (isset($parent_node['cat_id'])) ? $parent_node['cat_id'] : $id;
$catalist = '';
if ($parent_node['left_id'] != 1)
{
$children = $catscontrol->get_children_list($parent_node['left_id'], $parent_node['right_id']);
$childarray = array($id);
foreach ($children as $k => $v)
{
$childarray[] = $v['cat_id'];
}
$catalist = '(';
$catalist .= implode(',', $childarray);
$catalist .= ')';
$all_items = false;
}
$NOW = time();
/*
specified category number
look into table - and if we don't have such category - redirect to full list
*/
$query = "SELECT * FROM " . $DBPrefix . "categories WHERE cat_id = " . $id;
$result = mysql_query($query);
$system->check_mysql($result, $query, __LINE__, __FILE__);
$category = mysql_fetch_assoc($result);
if (mysql_num_rows($result) == 0)
{
// redirect to global categories list
header ('location: browse.php?id=0');
exit;
}
else
{
// Retrieve the translated category name
$par_id = $category['parent_id'];
$TPL_categories_string = '';
$crumbs = $catscontrol->get_bread_crumbs($category['left_id'], $category['right_id']);
for ($i = 0; $i < count($crumbs); $i++)
{
if ($crumbs[$i]['cat_id'] > 0)
{
if ($i > 0)
{
$TPL_categories_string .= ' > ';
}
$TPL_categories_string .= '' . $category_names[$crumbs[$i]['cat_id']] . '';
}
}
// get list of subcategories of this category
$subcat_count = 0;
$query = "SELECT * FROM " . $DBPrefix . "categories WHERE parent_id = " . $id . " ORDER BY cat_name";
$result = mysql_query($query);
$system->check_mysql($result, $query, __LINE__, __FILE__);
$need_to_continue = 1;
$cycle = 1;
$column = 1;
$TPL_main_value = '';
while ($row = mysql_fetch_array($result))
{
++$subcat_count;
if ($cycle == 1)
{
$TPL_main_value .= '<div class="col'.$column.'"><ul>' . "\n";
}
$sub_counter = $row['sub_counter'];
$cat_counter = $row['counter'];
if ($sub_counter != 0)
{
$count_string = ' (' . $sub_counter . ')';
}
else
{
if ($cat_counter != 0)
{
$count_string = ' (' . $cat_counter . ')';
}
else
{
$count_string = '';
}
}
if ($row['cat_colour'] != '')
{
$BG = 'bgcolor=' . $row['cat_colour'];
}
else
{
$BG = '';
}
// Retrieve the translated category name
$row['cat_name'] = $category_names[$row['cat_id']];
$catimage = (!empty($row['cat_image'])) ? '<img src="' . $row['cat_image'] . '" border=0>' : '';
$TPL_main_value .= "\t" . '<li>' . $catimage . '' . $row['cat_name'] . $count_string . '</li>' . "\n";
++$cycle;
if ($cycle == 7) // <---- here
{
$cycle = 1;
$TPL_main_value .= '</ul></div>' . "\n";
++$column;
}
}
if ($cycle >= 2 && $cycle <= 6) // <---- here minus 1
{
while ($cycle < 7) // <---- and here
{
$TPL_main_value .= ' <p> </p>' . "\n";
++$cycle;
}
$TPL_main_value .= '</ul></div>'.$number.'
' . "\n";
}
I was needing to divide the resulting links into three columns to fit my html layout.
We accomplished this by changing the numbers in the code marked with "// <---- here".
Because the amount of links returned could be different each time, I am trying to figure out how to change those numbers on the fly. I tried using
$number_a = mysql_num_rows($result);
$number_b = $number_a / 3;
$number_b = ceil($number_b);
$number_c = $number_b - 1;
and then replacing the numbers with $number_b or $number_c but that doesn't work. Any ideas?
As mentioned before, you can use the mod (%) function to do that.
Basically what it does is to get the remainder after division. So, if you say 11 % 3, you will get 2 since that is the remainder after division. You can then make use of this to check when a number is divisible by 3 (the remainder will be zero), and insert an end </div> in your code.
Here is a simplified example on how to use it to insert a newline after every 3 columns:
$cycle = 1;
$arr = range (1, 20);
$len = sizeof ($arr);
for ( ; $cycle <= $len; $cycle++)
{
echo "{$arr[$cycle - 1]} ";
if ($cycle % 3 == 0)
{
echo "\n";
}
}
echo "\n\n";

add an if echo statement to my search engine

I have a search engine and because of the paralympics, I want people to be able to see a h1 countdown I have placed at the top of my site. Underneath will be the looped results from my database. Any ideas where I go wrong? because in this if, it won't echo the h1 tag at all. I would like to above my results.
$query = " SELECT * FROM scan WHERE ";
$terms = array_map('mysql_real_escape_string', $terms);
$i = 0;
foreach ($terms as $each) {
if ($i++ !== 0) {
$query .= " OR ";
}
$query .= "keywords LIKE '%{$each}%'";
}
// Don't append the ORDER BY until after the loop
$query .= "ORDER BY rank";
$query = mysql_query($query) or die('MySQL Query Error: ' . mysql_error($connect));
$numrows = mysql_num_rows($query);
if ($numrows > 0) {
while ($row = mysql_fetch_assoc($query)) {
$id = $row['id'];
$title = $row['title'];
$description = $row['description'];
$keywords = $row['keywords'];
$link = $row['link'];
$rank = $row['rank'];
echo '<h2><a class="ok" href="' . $link . '">' . $title . '</a></h2>' . PHP_EOL;
echo '<p maxlength="10" class="kk">' . $description . '</p>' . PHP_EOL;
echo '<p><a class="okay" href="' . $link . '">' . $link . '<br><br><span class="keywords"></p>' . PHP_EOL;
}
} else {
echo "No results found for \"<b>{$k}</b>\"";
}
if ($k = "Paralympics 2012") {
echo "<h1> Countdown to Paralympics: 7 Days </h1>";
}
if ($k = "Paralympics 2012") {
echo "<h1> Countdown to Paralympics: 7 Days </h1>";
}
Will always print the <h1>. You're doing assignment rather than comparison. Try:
if ($k == "Paralympics 2012")
Also, verify that $k is what you expect it to be when debugging.
One equals (=) assigns, and two/three (==/===) compares. The line
if ($k = "Paralympics 2012") {
Assigns $k to a string, which always returns true, because any string other than an empty one ("") is truthy. Try this:
if ($k === "Paralympics 2012") {
First things first, the <h1> is always displaying, opposite of what you're question states. It's always displaying due to the fact that you're doing an assignment of a non-false value with:
if ($k = "Paralympics 2012") {
Update that to use a comparison to fix that logic issue.
if ($k == "Paralympics 2012") {
Next, to get it to display above your results, you need to actually move that if-statement above the loop that echos the results. Try placing it in the if ($numrows > 0) { block, like this:
if ($numrows > 0) {
if ($k == "Paralympics 2012") {
echo "<h1> Countdown to Paralympics: 7 Days </h1>";
}
while ($row = mysql_fetch_assoc($query)) {
...

How to write this statement using PHP & CodeIgniter

I'm trying to figure out how to write a statement in my first CI app (and only second PHP app ever) and I'm stuck.
I have a junction table that holds book_id and user_id from their respective tables. I want to find out who has read a book and echo that back out, but I need the formatting to make sense. Here is the query:
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
And here's my logic for one person
// Get my user info
$user = $this->ion_auth->get_user();
// Tell me who has read it.
$this->db->select('user_id');
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
// If only one person has read it
if ($readQuery->num_rows() == 1) {
$readResult = $readQuery->row();
// And if that person was me...
if ($readResult->user_id == $user->id) {
$message = 'You have read this.';
// If it was someone else...
} else {
$reader = $this->ion_auth->get_user($readResult->user_id);
$message = "$reader->first_name $reader->last_name has read this";
}
// If two people have read it
}
So I'm good if only one person has read it. But when two people have read it, I want it to say "Name One and Name Two have read this." if the logged in person hasn't read it. If they're one of the two people, it should say "You and Name Two have read this".
And so on for 3-5. If 3-5 people have read it, the options would be "Name One, Name Two, and Name Three have read this" or "You, Name Two, and Name Three have read this." up to five people
And if it's 6 or more, it should just say the names of two of them, IE "You, Name Two, and 5 other people have read this."
I considered doing a conditional for each instance and then pushing all of the users to an array. Then I could use in_array() to see if the logged-in user has read it and try to report back, but I'm just having some trouble working up the logic.
Is there an easier way?
Thanks much in advance,
Marcus
I'd say use a switch statement with ranges. You'll have to do a bit of acrobatics to handle the issue of including "You" or not. The code below is untested but give you the general idea.
$message = "";
$readers = array();
$me_included = 0; // Counter increment if you're included in the reader list
$this->db->select('user_id');
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
foreach ($readQuery->result() as $row) {
if ($row->user_id == $user->id) {
$message = "You";
$me_included = 1;
} else {
$readers[] = $this->ion_auth->get_user($row->user_id);
}
}
$reader_count = $sizeof($readers) + $me_included;
switch(TRUE)
{
// One reader, not you
case( ($reader_count == 1) && ($me_included == 0) ):
$message .= $readers[0]->first_name . " " . $readers[0]->last_name . " has read this.";
break;
// Only you
case( ($reader_count == 1) && ($me_included == 1) ):
$message .= " have read this.";
break;
// Two readers
case( ($reader_count == 2) ):
for ($i = 0; $i <= sizeof($readers); $i++) {
if ($i == sizeof($readers)) {
$message .= " and ";
}
$message .= $readers[i]->first_name . " " . $readers[i]->last_name;
}
$message .= " have read this.";
break;
case( ($reader_count > 3) && ($reader_count < 6) ):
if ($me_included) {
$message .= ", ";
}
for ($i = 0; $i <= sizeof($readers); $i++) {
if ($i == sizeof($readers)) {
$message .= " and ";
}
$message .= $readers[i]->first_name . " " . $readers[i]->last_name;
if ($i != sizeof($readers)) {
$message .= ", ";
} else {
$message .= " have read this.";
}
}
break;
case( ($reader_count > 6) ):
if ($me_included) {
$message .= ", " . $readers[0]->first_name . " " . $readers[0]->last_name . " and " . ($reader_count - 2) . " others have read this.";
} else {
for ($i = 0; $i <= 1; $i++) {
$message .= $readers[0]->first_name . " " . $readers[0]->last_name . ", " . $readers[1]->first_name . " " . $readers[1]->last_name . " and " . ($reader_count - 2) . " others have read this.";
}
break;
}
$users = array();
while($row)
{
if(currentuser)
{
array_unshift($users,'You')
}
else
{
$users[] = row[name]
}
}
$count = $max = count($users);
if($max >= 6)
{
$max = 2;
}
$str = '';
for($i=0;$i<$max;$i++)
{
$str .= ($str == '' ? '' : ($i == $count-1 && $count < 6 ? ' And ' : ', ') ) . $users[$i];
}
if($count >= 6)
{
$str .= ' and '.$count-2.' others'
}
This should help you along. It's pretty much pseudo-code but the logic is there to achieve what you want (I believe). You'd obviously want to not fetch all the rows if you are just showing a number of users but that can easily be accomplished.
There are actually a couple places we can optimize this.
1) In the initial query do a JOIN with the user table so we don't have to query again multiple times just for each name:
$readers = $this->db->select('id', 'first_name', 'last_name')->from('books_users')->join('users', 'books_users.id =users.id', 'left')->where('book_id' => $isbn);
2) Additionally, we can avoid iterating over the entire (potentially large) result set just to see if you read it, by doing a separate query:
$you_read = $this->db->get_where('books_users', array('book_id' => $isbn, 'user_id' => $user->id));
Just for the sake of completeness, here is the final code I used. Hopefully it will be of use to someone.
// Find out who has read this book
// Get the users
$current_user = $this->ion_auth->get_user();
$users = $this->ion_auth->get_users();
// Get the readers
$this->db->select('user_id');
$query = $this->db->get_where('books_users', array('book_id' => $isbn));
// If there were results
$readers = array();
if ($query->num_rows() > 0) {
foreach ($users as $user) {
if ($current_user->id == $user->id) {
array_unshift($readers, 'You');
} else {
$readers[] = $user->first_name . ' ' . $user->last_name;
}
$count = $max = count($readers);
if ($max >= 6) {
$max = 2;
}
$message = '';
for ($i = 0; $i < $max; $i++) {
$message .= ($message == '' ? '' : ($i == ($count - 1) && ($count < 6) ? ' and ' : ', ')) . $readers[$i];
}
if ($count >= 6) {
$message .= ' and ' . ($count - 2) . ' others';
}
$message .= ($count == 1 && !$current_user->id ? ' has ' : ' have ') . 'read this.';
}
} else {
$message = 'Be the first to read this.';
}

Categories