Im trying to return true when my loop has finished but it does not seem to happen.
I can get it to echo true or false or any text but returning does nothing.
Wonder if anyone could explain why this is.
Here is the (kinda) function I have removed the data base calls and such as its not important.
function loop_me(){
// this part is not important...
$finished = false;
$done = 0;
$userC = 1000;
$page = 0;
$count = 10;
$array = array()
$data = array('1','2','3') // big array of data...
if($done < $userC){
for($i=0; $i<$count; $i++){
$array[] = $data[$i];
}
// bellow is the important part...
if($done >= $userC){
$finished = true;
}else{
$page++;
loop_me();
}
}
if($finished){
// If I echo true it outputs 1 (this is fine)
// if I return true I get nothing this is got good as I want to do an IF statement on the
// output, which I can't do if it does not.
echo(true);
}
}
Ok so the function with the issue is above but just to help you out, the basic idea of the function is that i loops thought an array of data (not showen above) but this data is paginated so it needs to go to the next 'page' once its finished with the first and there a few pages so what I want to do is when it has finished looping thought it all return true.
Might be a simple fix.
But I can't work it out.
You called 'loop_me()' recursively, but you need to return it.
}else{
$page++;
return loop_me();
}
and of course change echo to return too!
edit your echo (true); to something like: return true; then call your function:
$var = loop_me();
echo $var; // If a success you should see true.
You should also consider adding a return false if there is a problem when calling your defined function.
Related
I have function calling itself. There is a number of max repeats and repeat counter. The function is calling itself until reaching a point where repeat counter is equal to max repeats. If I uncomment messages inside a function, I can see everything working as it should. But if I want to return an array of positions, there is no result:
function myFunction($positions, $maxRepeats, $repeatCounter = 0){
if($repeatCounter < $maxRepeats){
// echo 'Test message - loop ' . $repeatCounter;
$positions[] = array('title' => $repeatCounter);
$repeatCounter++;
myFunction($positions,$maxRepeats,$repeatCounter);
} else {
// echo 'Test message - end ' . $repeatCounter;
return $positions;
}
}
$positions = array();
$result = myFunction($positions,2);
print_r($result);
Thanks for any idea.
Because if this condition is true:
if($repeatCounter < $maxRepeats)
Then the function never encounters a return statement. It looks like you meant to return the recursive result:
return myFunction($positions,$maxRepeats,$repeatCounter);
I'm trying to go next page and for that wrote while(true) loop, but not working properly. Giving me no error or anything just nothing.
This is the web site link: https://suumo.jp/ms/shinchiku/osaka/sa_osaka/pnz11.html I'm trying to add +1 to pagination
$startID = 1;
while(true) {
#$url = "https://suumo.jp/ms/shinchiku/osaka/sa_osaka/pnz1".$startID.".html";
$html = #file_get_contents($url);
if($http_response_header[0] == 'HTTP/1.1 200 OK') {
libxml_use_internal_errors(true);
$parser = new \DOMDocument();
$parser->loadHTML($html);
And end of the code.
$a = $startID+1;
} else {
$this->error("Next page is not found!");
}
By the way I am scraping first page with no problem. But it isn't go next page. Any idea for why is that happening?
You are not increment the $startID you have $a=$startID+1. So each iteration of your loop $startID is equal to 1. To fix it you need to add it to itself with either:
$startID += 1;
//or
++$startID;
//or (if you really need $a)
$a = $startID += 1;
And change this:
} else {
$this->error("Next page is not found!");
break; //exit the loop
}
I should mention that for(;;) is roughly equivalent to while(true) So this:
for($startID=1;;++$startID){ ... }
Is roughly equivalent to all this:
$startID = 1;
while(true){
++$startID;
}
Except it's much prettier in my Opinion. I feel like a lot of coders overlook for in PHP, the arguments are actually optional, too.
Enjoy.
I need to identify every instance where a value in one array (needle) occurs in another array (haystack). in_array() seems to be my best option, and the code below works perfectly until I need to use it on rows fetched from a db - it keeps appending values instead of setting them each time it's called.
While I can't actually use unset() in this situation, I was surprised to discover that even that didn't seem to resolve the problem.
UPDATE - Example of what's being returned
I temporarily changed the db values so that $needles has only value per row (in order to make it possible to sort through the values filling up my screen ;-))
False;
False; False; True;
False; False; True; False; True;
False; False; True; False; True; False; True;
False; False; True; False; True; False; True; False;
This works correctly
(I've posted a functional example here)
$needles = array('John', 'Alex');
$haystack = array('John','Alexander','Kim', 'Michael');
foreach ($needles as $needle) {
if (in_array($needle, $haystack) ) {
$Match = 'True';
}
else {
$Match = 'False';
}
}
This keeps appending values - Edited to reflect the code I'm using
$Customer_Categories_Arr = array('Casual','Trendy');
if ($stmt->columnCount()) {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$Product_Categories_Arr[]=$row["Taste_Category"];
// Use when column contains CSV
// $Product_Categories_Arrx = explode(',', trim($Product_Categories_Arr[0]));
foreach ($Product_Categories_Arr as $Product_Category_Arr) {
if (in_array($Product_Category_Arr, $Customer_Categories_Arr)){
$Matches_Product_Category = "True";
} else {
$Matches_Product_Category = "False";
}
echo $Product_Category_Arr, ', ', $Matches_Product_Category, '; ';
}
}
}
It is not really clear what you are trying to do. But maybe this would help:
$customerCategories = array('Casual', 'Trendy');
if( $stmt->columnCount() ){
while( $row = $stmt->fetch( PDO::FETCH_ASSOC )){
$productCategoryRow = $row[ 'Taste_Category' ];
// If it is not working, try uncommenting the next line
// $productCategories = [];
$productCategories = explode( ',', trim( $productCategoryRow ));
$match = "False";
foreach( $productCategories as $productCategory ){
if( in_array( $productCategory, $customerCategories )){
$match = "True";
}
echo $match . ";";
}
}
}
This prints your result on the screen every time a loop is done. Is this what you mean?
If you want the second block of code to do what the first block of code (which works correctly) does, then the second block should look like this -
if ($stmt->columnCount()) {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$needle =$row["product_var"];
$Match = "False";
if (in_array($needle, $haystack)){
$Match = "True";
}
}
}
You don't need do use the foreach because that is replaced by the while loop in the second block.
I am going to try an solve this. I think the problem is with:
$needles[]=$row["product_var"];
I think this should be:
$needles=$row["product_var"];
The column "product_var" contains an CSV (as you mentioned), so I can make an example like this:
$csv = "jake;john;alex;kim";
An example with brackets ($needles[]):
for($i=0; $i<5; $i++) {
$needles[] = explode(";", $csv);
echo(count($needles).", ");
}
returns:
1, 2, 3, 4, 5,
edit (for more explaining):
if I use print_r I see the array expanding, exactly how it happens in your example:
step 1: it adds an array to $needles with values ('jake','john','alex','kim')
step 2: it adds an array to $needles, so it contains 2x the values ('jake','john','alex','kim')
step 3: it adds an array to $needles, so it contains 3x the values ('jake','john','alex','kim')
etc.
Now without the brackets ($needles):
for($i=0; $i<5; $i++) {
$needles = explode(";", $csv);
echo(count($needles).", ");
}
This returns:
4, 4, 4, 4, 4,
And every time the array simply contains the values ('jake','john','alex','kim') -which is what you want.
Could this explain the "expanding values"? (or am I just doing something really stupid which has nothing to do with your problem??)
edit:
If this is what is going wrong, then you are adding to an array, instead of only using the new array from $row["product_var"] (hope this makes any sense; it seems I am pretty bad at explaining what's happening).
for some reason $post is always < 0. The indoxOf function works great. I use it on ohter codes and it works great
for some reason even after I add the element like this array_push($groups, $tempDon); on the next loop i continues to return -1
$donations = $this->getInstitutionDonations($post->ID);
$groups=array();
foreach( $donations as $don ) : setup_postdata($don);
$pos = $this->indexOf($don, $groups);
print_r($pos);
if($pos < 0)
{
$tempDom = $don;
$tempDon->count = 1;
array_push($groups, $tempDon);
}
else
{
$tempDom = $groups[$pos];
$tempDon->count++;
array_splice($tempDon);
array_push($groups, $tempDon);
echo '<br><br><br>ahhhhhhhhhh<br><br>';
}
endforeach;
protected function indexOf($needle, $haystack) { // conversion of JavaScripts most awesome
for ($i=0;$i<count($haystack);$i++) { // indexOf function. Searches an array for
if ($haystack[$i] == $needle) { // a value and returns the index of the *first*
return $i; // occurance
}
}
return -1;
}
This looks like an issue of poor proofreading to me (note $tempDom vs $tempDon):
$tempDom = $don;
$tempDon->count = 1;
array_push($groups, $tempDon);
Your else block has similar issues.
I also completely agree with #hakre's comment regarding syntax inconsistencies.
EDIT
I'd also like to recommend that you make use of PHP's built-in array_search function in the body of your indexOf method rather than rolling your own.
I have the following PHP code which works out the possible combinations from a set of arrays:
function showCombinations($string, $traits, $i){
if($i >= count($traits)){
echo trim($string) . '<br>';
}else{
foreach($traits[$i] as $trait){
showCombinations("$string$trait", $traits, $i + 1);
}
}
}
$traits = array(
array('1','2'),
array('1','2','3'),
array('1','2','3')
);
showCombinations('', $traits, 0);
However, my problem is that I need to store the results in an array for processing later rather than just print them out but I can't see how this can be done without using a global variable.
Does anyone know of an alternative way to achieve something similar or modify this to give me results I can use?
Return them. Make showCombinations() return a list of items. In the first case you only return one item, in the other recursive case you return a list with all the returned lists merged. For example:
function showCombinations(...) {
$result = array();
if (...) {
$result[] = $item;
}
else {
foreach (...) {
$result = array_merge($result, showCombinations(...));
}
}
return $result;
}
In addition to the other answers, you could pass the address of an array around inside your function, but honestly this isn't nearly the best way to do it.
Using the variable scope modifier static could work. Alternatively, you could employ references, but that's just one more variable to pass. This works with "return syntax".
function showCombinations($string, $traits, $i){
static $finalTraits;
if (!is_array($finalTraits)) {
$finalTraits = array();
}
if($i >= count($traits)){
//echo trim($string) . '<br>';
$finalTraits[] = $string;
} else {
foreach($traits[$i] as $trait){
showCombinations("$string$trait", $traits, $i + 1);
}
}
return $finalTraits;
}
$traits = array(
array('1','2'),
array('1','2','3'),
array('1','2','3')
);
echo join("<br>\n",showCombinations('', $traits, 0));
Of course, this will work as expected exactly once, before the static nature of the variable catches up with you. Therefore, this is probably a better solution:
function showCombinations($string, $traits, $i){
$finalTraits = array();
if($i >= count($traits)){
$finalTraits[] = $string;
} else {
foreach($traits[$i] as $trait){
$finalTraits = array_merge(
$finalTraits,
showCombinations("$string$trait", $traits, $i + 1)
);
}
}
return $finalTraits;
}
although the solution by Lukáš is the purest as it has no side effects, it may be ineffective on large inputs, because it forces the engine to constantly generate new arrays. There are two more ways that seem to be less memory-consuming
have a results array passed by reference and replace the echo call with $result[]=
(preferred) wrap the whole story into a class and use $this->result when appropriate
the class approach is especially nice when used together with php iterators
public function pageslug_genrator($slug,$cat){
$page_check=$this->ci->cms_model->show_page($slug);
if($page_check[0]->page_parents != 0 ){
$page_checks=$this->ci->page_model->page_list($page_check[0]->page_parents);
$cat[]=$page_checks['re_page'][0]->page_slug;
$this->pageslug_genrator($page_checks['re_page'][0]->page_slug,$cat);
}
else
{
return $cat;
}
}
this function doesnt return any value but when i m doing print_r $cat it re
store the results in a $_SESSION variable.