conditional in_array trouble with PHP mySQL - php

I have firePHP so i know exactly what the variables are, but I can't figure out why this code doesn't change it.
I receive from a mySQL call $query (which if returned produces [{"type":"2"}])
I have 4 potential types, and things can be multiple types (i.e. [{"type":"1"},{"type":"2"}])
Now I want to read this data and run various other functions based on the type it has, that is: if it's only type 2, call function TWO, if it's type 1 and 2 call function ONE and function TWO. I thought this would be easiest if i moved all the data into another array.
Here is the code I currently have:
$result = array('message'=>false, 'money'=>false, 'glasses'=>false, 'exclamation'=>false);
if (in_array('1',$query)) {$result['message'] = true;}
if (in_array('2',$query)) {$result['money'] = true;}
if (in_array('3',$query)) {$result['glasses']=true;}
if (in_array('4',$query)) {$result['exclamation']=true;}
echo json_encode($result);
This however does not update the $result array (as I can tell all of the values of $message are false in firePHP.... Thus I assume something is wrong with my if statements, but what?

I´m not sure about the value of $query, but if it is something like:
array [0 => '{"type":"2"}']
You would have to use:
in_array('{"type":"2"}',$query)
as that is the value of your variable.

Is it because the results returned in $query are arrays of arrays, and thus in_array is only searching at the top level and not sub-levels? It seems like what you want is to recursively search $query.

Related

Can you get value from an array without getting the array first?

Bear with me, I'm learning.
I often see snippets like the one below:
<?p
$imageArray = get_field('image_field');
$imageAlt = $imageArray['alt'];
$imageURL = $imageArray['url'];
?>
It is pedagogical and clear and organized. But is it necessary to get the entire array before querying the array for values? Can I not define the variable in just a single line? Something like the below (which doesn't work, neither the other variants I have tried):
$imageAlt = get_field('image_field', ['alt']);
$imageURL = get_field('image_field', ['url']);
Yes, you can.
As of PHP 5.4 it is possible to array dereference the result of a function or method call directly. Before it was only possible using a temporary variable. - Source
$imageAlt = get_field('image_field')['alt'];
https://eval.in/548036
The question you are asking can be answered by asking 2 questions:
Is it doable ?
Is it a good idea to do it that way ?
Is it doable ?
Yes! You do not have to store the array in a variable and re-use it later.
For instance, you could do:
$imageAlt = get_field('image_field')['alt'];
Note: This will work in PHP 5.4+ and is called: Array dereferencing.
But that is not the only consideration...
Is it a good idea to do it that way ?
No. It's not a good idea in many cases. The get_field() function, depending on your context, is probably doing a lot of work and, each time you call it, the same work is don multiple times.
Let's say you use the count() function. It will count the number of items in an array. To do that, it must iterate through all items to get the value.
If you use the count() function each time you need to validate number of items in an array, you are doing the task of counting each and every time. If you have 10 items in your array, you probably won't notice. But if you have thousands of items in your array, this may cause a delay problem to compute your code (a.k.a. it will be slow).
That is why you would want to do something like: $count = count($myArray); and use a variable instead of calling the function.
The same applies to your question.
While PHP 5.4+ allows you to directly dereference a function return value like this:
get_field('image_field')['alt']
...in this particular case I would not suggest you do so, since you're using two values from the resulting array. A function call has a certain overhead just in itself, and additionally you don't know what the function does behind the scenes before it returns a result. If you call the function twice, you may incur a ton of unnecessary work, where a single function call would have done just as well.
This is not to mention keeping your code DRY; if you need to change the particulars of the function call, you now need to change it twice...
PHP allows you to play around quite a bit:
function foo(){
return array('foo' => 1, 'bar' => 2);
}
Option 1
echo foo()['foo']; // 1
# Better do this if you plan to reuse the array value.
echo ($tmp = foo())['foo']; // 1
echo $tmp['bar']; // 2
It is not recommended to call a function that returns an array, to specifically fetch 1 key and on the next line doing the same thing.
So it is better to store the result of the function in a variable so you can use it afterwards.
Option 2
list($foo, $bar) = array_values(foo());
#foo is the first element of the array, and sets in $foo.
#bar is the second element, and will be set in $bar.
#This behavior is in PHP 7, previously it was ordered from right to left.
echo $foo, $bar; // 12
Option 3
extract(foo()); // Creates variable from the array keys.
echo $foo, $bar;
extract(get_field('image_field'));
echo $alt, $url;
Find more information on the list constructor and extract function.

Custom buffering of php mysql results - strange issue

I discovered something very strange with my PHP code and mysqli functions. When I have my code in the format below:
function mainline(){
$q=mysqli_query($this->conn,"select * from table",MYSQLI_USE_RESULT);
$dataset=parse($q);
}
function parse($q){
if (!$q){return NULL;}
while($res=mysqli_fetch_array($q)){$r[]=$res;}
mysqli_free_result($q);$q=NULL;$res=NULL;return $r;
}
I'm able to retrieve data and process it. In the above example, data is returned to $dataset and each element is retrieved in the form of $dataset[row number][field name].
Now when I change my code so its like this:
function mainline(){
$q=mysqli_query($this->conn,"select * from table",MYSQLI_USE_RESULT);
$dataset=parse($q);
}
function parse($q){
if (!$q){return NULL;}
while($r[]=mysqli_fetch_array($q)); // I made change here
mysqli_free_result($q);$q=NULL;return $r;
}
The data returned is always nothing even though the select statement is exactly the same and always returns rows. During both tests, nothing has modified the data in the database.
My question then is why does while($res=mysqli_fetch_array($q)){$r[]=$res;} retrieve correct results and while($r[]=mysqli_fetch_array($q)); does not?
With the second while loop, I won't have to allocate an extra variable and I'm trying to cut down on the use of system memory so that I can run more apache processes on my system instead of waste memory unnecessarily on PHP.
Any ideas why while($r[]=mysqli_fetch_array($q)); wont work? or any ideas how I can make it work without using an extra variable? or am I stuck?
if you want to store all result in array than why not use
mysqli_fetch_all($q)
and store result in whatever you want. Though if you want to have quick access I
think caching sounds more appropriate.
mysqli_fetch_all — Fetches all result rows as an associative array, a numeric array, or both

Use a parameter as an index in PHP

I am trying to do a thing that I dont know if can work. Also accept other ideas.
I have an array passed as a parameter where the index is the task id in the database and the value is the last syncronization for the task with the database
$sync=Array
(
[22805] => 1406822699
[22806] => 1406824500
[22807] => 1406838670
)
Then I do a select in the database which gives me the whole of tasks and I one to update on the database only some tasks, basically the ones that are out of date.
//$tasks is the list of all tasks from the database and $sync is the array which is pased by the user
foreach($tasks as $task)
{
if($task['sync']<=$sync[$task['taskList_id']])
{}
else
{//to be updated
$taskModel->updateLastSync($task['taskList_id'],$time);
$task['sync']=$time;
}
}
This is the problematic line and what I need to know how to do.
$sync[$task['taskList_id']]
I want to use a parameter as index to get the value of an array.
How can I achieve this.
Because this other idea is another foreach for $sync inside the foreach for $tasks
Without seeing the full script or having access to var_dump at certain locations it's hard to say what's going on but here are some things to check:
Make sure you're getting results from the database query and that they are assigned to the $tasks variable
Make sure your $sync array values and $task['sync'] are integer types and not strings or the '<=' comparison may have unexpected results
I don't know where $time gets its value from based on code I see so verify that it does actually have a value when you try to set it
A good first step when debugging is to try to isolate the problem's location first and then worry about the cause. Using something like var_dump to verify that values of certain variables are as expected at various locations in your script is very useful. Once you know where things start going wrong you can focus your attention in the right place to find out why and come up with a solution. I recommend doing this and letting us know what you find.
I solved my question.
Which was if this is allowed, I tested and it is.
$ar=array('1'=>'a','2'=>'b','3'=>'c');
$index=2;
echo $ar[$index];

An imported array from mysql works, but the array can't be used by php as an array?

The code below won't work because of this line $params=array($data);. It needs something other than $data. Or it needs something to happen with $data prior to this line.
If the line is written as $params=array("A", "B", "C", "D"); then it works great, but my array is in the $data variable, not written out like that. If there is a way to get the array converted to being written out like that, that would work too.
The end result should show every possible combination (not permutation) of the contents of the array. Like in the example above it shows ABC, BD, etc.
$data = mysql_query('SELECT weight FROM my_table WHERE session_id = "' . session_id() . '"');
$params=array($data);
$combinations=getCombinations($params);
function getCombinations($array)
{
$length=sizeof($array);
$combocount=pow(2,$length);
for ($i=1; $i<$combocount; $i++)
{
$binary = str_pad(decbin($i), $length, "0", STR_PAD_LEFT);
$combination='';
for($j=0;$j<$length;$j++)
{
if($binary[$j]=="1")
$combination.=$array[$j];
}
$combinationsarray[]=$combination;
echo $combination."<br>";
}
return $combinationsarray;
}
mysql_query() only returns a result resource ID. To retrieve data, you must use one of the "fetch" commands, for example
$params = array();
while ($row = mysql_fetch_assoc($data)) {
$params[] = $row['weight'];
}
Also, your query is possibly vulnerable to SQL injection. I wouldn't implicitly trust the value from session_id(). I'm not entirely sure of this but it may simply retrieve the value from the session cookie.
At the very least, sanitise the value with mysql_real_escape_string(). A more robust solution which would bring your code out of the dark ages would be to use PDO and parameter binding.
$data is not an array. Assuming mysql_query() did not return an error or an empty result (both of which you should check for, by the way--lookup documentation for mysql_error() and mysql_num_rows() perhaps, maybe some others), $data is a resource.
So you want $params=mysql_fetch_array($data) to make it an array. (That assumes that there is only one result. If it might return more than one row, you'll probably want to wrap it in a loop. If you are 100% certain that session_id is unique , then you can get away without the loop, I suppose. You can also get away without the loop if you only care about the first result in a multi-row result, although I'd throw in a LIMIT 1 in your query in that case to improve performance.)
There are lots of options (do you want a numerically indexed array, or one where they keys are the names of the columns, etc.) so read up at http://www.php.net/manual/en/function.mysql-fetch-array.php.
Ok there are alot of fundamental problems with your script. I personally recommend to first read this article and then about the actual function called mysql_fetch_array().
Simply put, what you are receiving from mysql is resource (corrent me if i'm wrong!) and you have to fetch array on that.
$params = mysql_fetch_array($data);
PS: This makes no sense: $params=array($data);

How to ungroup an element in an multi-dimentional array?

I have a function that gets users from a MySQL database, the results rows can be 1 or multiple rows.
What annoys me is that when i'm only looking to get 1 result from the db, it returns me a multi-dimentional array like this:
$result = array([0]=>array('foo'=>'bar'))
And makes me write nasty code like:
$e = $result[0]['foo'] // instead of $result['foo']
I'm pretty sure that many people came across this situation, i thought it would be cool if i can check if there is only one row returned and then append to $result an ungrouped version of it so i can use it when i'm looking for only 1 row. so it'd be like this:
$result = array(
[0] => array('foo'=>'bar'), // will keep the multi-dimentional version
'foo' => 'bar' // and append the ungrouped version of $result here
);
How to do that?
if ( count($result) === 1)
{
$result = $result[0];
}
Sounds to me like something's a little wonky in your API.
If you have a function that can return 1 to n results from a database, then it should be accessed through array accessors (such as $result[0]['foo']). Alternatively, you could store the result in a temp var, such as:
$o = $result[0];
print_r($o['foo']);
The problem with doing what you're asking is that you're munging your return data on a special case basis, which is not only confusing to those who may use your code, but it's very error-prone, potentially leaving a user wondering why they can't access the 0th element of $result.
Functions that return a single element should return a single element. Functions that return multiple elements should return multiple elements (and not have their data changed on special cases).

Categories