Php index of element in the array, update element - php

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.

Related

Ensure order in for loop involving json_decode()

I'm using json_decode to parse JSON files. In a for loop, I attempt to capture specific cases in the JSON in which one element or another exist. I've implemented a function that seems to fit my needs, but I find that I need to use two for loops to get it to catch both of my cases.
I would rather use a single loop, if that's possible, but I'm stuck on how to get both cases caught in a single pass. Here's a mockup of what I would like the result to look like:
<?php
function extract($thisfile){
$test = implode("", file($thisfile));
$obj = json_decode($test, true);
for ($i = 0; $i <= sizeof($obj['patcher']['boxes']); $i ++) {
//this is sometimes found 2nd
if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring1") {
}
//this is sometimes found 1st
if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring2") {
}
}
}
?>
Can anyone tell me how I could catch both cases outlined above within a single iteration?
I clearly could not do something like
if ($obj['patcher']['boxes'][$i]['box']['name'] == "string1" && $obj['patcher']['boxes'][$i]['box']['name'] == "string2") {}
...because that condition would never be met.
Generally what I do when I have raw data that is in an order that isn't ideal to work with is to run a first loop pass to generate a a list of indexes for me to pass through a second time.
So a quick example from your code:
<?php
function extract($thisfile){
$test = implode("", file($thisfile));
$obj = json_decode($test, true);
$index_mystring2 = array(); //Your list of indexes for the second condition
//1st loop.
$box_name;
for ($i = 0; $i <= sizeof($obj['patcher']['boxes']); $i ++) {
$box_name = $obj['patcher']['boxes'][$i]['box']['name'];
if ( $box_name == "mystring1") {
//Do your code here for condition 1
}
if ($box_name == "mystring2") {
//We push the index onto an array for a later loop.
array_push($index_mystring2, $i);
}
}
//2nd loop
for($j=0; $j<=sizeof($index_mystring2); $j++) {
//Your code here. do note that $obj['patcher']['boxes'][$j]
// will refer you to the data in your decoded json tree
}
}
?>
Granted you can do this in more generic ways so it's cleaner (ie, generate both the first and second conditions into indexes) but i think you get the idea :)
I found that something like what #Jon had mentioned is probably the best way to attack this problem, for me at least:
<?php
function extract($thisfile){
$test = implode("", file($thisfile));
$obj = json_decode($test, true);
$found1 = $found2 = false;
for ($i = 0; $i <= sizeof($obj['patcher']['boxes']); $i ++) {
//this is sometimes found 2nd
if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring1") {
$found1 = true;
}
//this is sometimes found 1st
if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring2") {
$found2 = true;
}
if ($found1 && $found2){
break;
}
}
}
?>

Can echo true but wont return

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.

How Can I get the string that present the variable in function argument?

How Can I get the string that present the variable in function argument?
example
function dbg($param){
return "param";
}
$var="Hello World";
echo dgb($var);
output: var
$arr=array();
echo dgb($arr);
output: arr
It is NOT possible to do what you ask reliably.
The closest you can come up to doing that is to do a debug_backtrace() to check which file called the function then tokenize the source of that file to find the reference.
Again, this will not work reliably. It will fail if you have multiple calls on one line. Truthfully, it isn't work the trouble. You are writing the code anyway, you know which variable you are passing.
function dbg($var) {
$bt = debug_backtrace();
$file = $bt[0]['file'];
$line = $bt[0]['line'];
$source = file_get_contents($file);
$tmpTokens = token_get_all($source);
$tokens = array ();
foreach ($tmpTokens as $token) {
if (is_array($token) && $token[0] !== T_INLINE_HTML && $token[0] !== T_WHITESPACE) {
$tokens[] = $token;
}
}
unset($tmpTokens);
$countTokens = count($tokens);
for ($i = 0; $i < $countTokens; $i++) {
if ($tokens[$i][3] > $line || $i === $countTokens - 1) {
$x = $i - (($tokens[$i][3] > $line) ? 1 : 0);
for ($x; $x >= 0; $x--) {
if ($tokens[$x][0] === T_STRING && $tokens[$x][1] === __FUNCTION__) {
if ($x !== $countTokens - 1 && $tokens[$x + 1][0] === T_VARIABLE) {
return $tokens[$x + 1][1];
}
}
}
}
}
return null;
}
printing a variable, you're doing it wrong.
the right ways is like this:
function dbg($param){
return $param;
}
$var="Hello World";
echo dgb($var);
and by the way you're passing an array to a function that only accepts variables. and oh it's a null array all the way worse!
I'm just guessing that you're trying to make a custom debugger which as a nice touch prints the name of the variable you're debugging. Well, that's not really possible. I'd suggest you look at debug_backtrace, which allows you to print the file, line number, function name and arguments of the place where you invoked your dbg function. Unless you use dbg more than once per line that helps you find the information you're looking for, and IMO is a lot more useful anyway.
Alternatively, you can have both the name and value of your variable if you call your function like this:
function dbg($var) {
echo 'name: ' . key($var) . ', value: ' . current($var);
}
$foo = 'bar';
dbg(compact('foo'));
You question doesnt make much sense, you may want to reword it.
It sounds like you want to use the $param in the function in which case you can just do something link echo $param;

Return an array from PHP function to Smarty

At the risk of self-embarrassment, could anyone tell me how to use return here:
function dayCount() {
for ($dayBegin = 1; $dayBegin < 32; $dayBegin++)
{
"<option value=\"".$dayBegin."\">".$dayBegin."</option>";
}
}
My issue is that I am passing this function to Smarty via
$dayCount = dayCount();
$smarty->assign('dayCount', $dayCount);
and
{$dayCount}
but instead the HTML is going straight to the buffer, right before <html> (thanks Hamish), not inside the HTML element I want.
Any help on this?
You need to build up the return statement
function dayCount() {
$return = array();
for ($dayBegin = 1; $dayBegin < 32; $dayBegin++)
{
$return[] = "<option value=\"".$dayBegin."\">".$dayBegin."</option>";
}
return $return;
}
Although this is building up an array like you asked. When outputting it, you would need to implode it.
implode('', $dayCount);
Or otherwise, build up a string instead of an array.

How do I store the results of this recursive function?

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.

Categories