Referencing Arrays in PHP - Questions - php

I am trying to understand the following code in PHP. Here is the overview,
There are 2 arrays, which consists of key values pairs in the form, $k => $v
These 2 arrays are merged together using array_merge function to form the third array.
Now, this array is passed to a function. Only one argument, the array name is passed.
Here is the code (please note that this code is only a concept, not the real code):
<?php
function test(&$myArray, 0)
{
reset($myArray);
foreach ($myArray as $k => $v)
{
....
}
}
$arr3 = array_merge((array) $arr1, (array) $arr2);
test($arr3)
}
Questions:
The function is defined in such a way, that it expects two arguments, however we are passing only one argument. Is it because the second argument is always 0 as initialized in the function prototype? So, there is no need to pass the same number of arguments?
Here the array name is passed. My guess is that, it will pass a pointer to the first element of the array (base address of the array in memory) to the function.
In this case, if you look at the prototype, the array name is preceded with an ampersand. So, this means, a reference to the array, the address?
Why is it necessary to call the reset function on the array. Is it because the array_merge function which was used to form this array was called before the test function? So, it moved the pointer in the array ahead of the first element as a result of merging $arr1 and $arr2?
There is no value returned in the function, test. So, does it modify the value of the original array in the memory itself, and hence there is no need to return an array?
Thanks.

<?php
function test($myArray,$a =0) //passing by value
{
reset($myArray);
return $myArray;
}
$arr3 = test($arr3); //call n store it back it in $arr3
function test(&$myArray,$a =0) //passing by reference
{
reset($myArray);
}
test($arr3); //just call;
?>

Related

Applying the same function to each array key in an increasing order in php

I am using an array in php that updates certain values in the array with the help of a function. The function works perfect but I want to apply the function to each element in an array in a increasing order.
Below is the function name.
CalculateDate($swappedarray,$row,$SetupTime);
The argument $row is the key number for each array element.
I want the function to do something like this.
CalculateDate($swappedarray,0,$SetupTime);
CalculateDate($swappedarray,1,$SetupTime);
CalculateDate($swappedarray,2,$SetupTime);
And so on until the last key number.
While the function works correct. I am just not able to use the for loop for doing this. The code for the 'for loop' which does not work and i tried is as follows.
for ($row = 0; $row <= $maxnum; $row++)
{
CalculateDate($swappedarray,$row,$SetupTime);
}
How can I make the function do what I need to do as explained above. Which is apply the function to each array key?
Would this work for your problem? (Substitute '$inputarray' for your starting array)
function some_callback($rowitem, $key, $userdata)
{
// echo $key;
CalculateDate($userdata[0], $key, $userdata[1);
}
array_walk($inputarray, 'some_callback', array($swappedarray, $SetupTime));
Basically, array walk is good for calling a function of your choice for each value in the array (similar to array_map, except array_walk makes it easier to pass additional arguments to the callback function).
In this code, we pass your $swappedarray and $SetupTime to the callback by putting them in an array. If $swappedarray does not change as you call CalculateData, it might be better to do the following to avoid recreating the same array:
function some_callback($rowitem, $key, $userdata)
{
// echo $key;
CalculateDate($userdata[0], $key, $userdata[1);
}
$walk_arguments = array($swappedarray, $SetupTime);
array_walk($inputarray, 'some_callback', array($swappedarray, $walk_arguments));
Let me know how it works out for you.
https://secure.php.net/manual/en/function.array-walk.php
https://secure.php.net/manual/en/function.array-map.php
I just passed the array name in the function argument as a reference and it worked.
CalculateDate(&$swappedarray,$row,$SetupTime);

Remove element from associative array in PHP

I need to remove a element from an associative array with an string structure.
Example:
$array = array(
"one"=>array("Hello", "world"),
"two"=>"Hi"
)
I want to create a function that removes the elements like this:
function removeElement($p) {
// With the information provided in $p something like this should happen
// unset($array["one"]["hello"])
}
removeElement("one.hello");
Your base array is associative, the inner array (key one) is not, its a indexed array, which you can not access via ["hello"] but rather [0].
You can remove the hello value by using the unset function, but the indexes will stay as they are:
$array = ['Hello', 'World']; // array(0: Hello, 1: World)
unset($array[0]); // Array is now array(1: World)
If you wish to keep unset and keep the array indexes in order, you can fetch the values using the array_values function after unset:
unset($array[0]);
$array = array_values($array); // array(0: World)
Or you could use array_splice.
When it comes to using a string as key for multidimensional array with a dot-separator I'd recommend taking a look at laravels Arr::forget method which does pretty much exactly what you are asking about.
This would be a static solution to your question, in any case, you need to use explode.
function removeElement($p, $array) {
$_p = explode('.', $p);
return unset($array[$_p[0]][$_p[1]]);
}
But bear in mind, this doesn't work if you have more in $p (like: foo.bar.quux)

Calling PHP function in itself

In the following script function clean($data) calls it within it, that I understand but how it is cleaning data in the statement $data[clean($key)] = clean($value);??? Any help is appreciated.. I am trying to figure it out as I am new to PHP. Regards.
if (ini_get('magic_quotes_gpc')) {
function clean($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[clean($key)] = clean($value);
}
} else {
$data = stripslashes($data);
}
return $data;
}
$_GET = clean($_GET);
$_POST = clean($_POST);
$_REQUEST = clean($_REQUEST);
$_COOKIE = clean($_COOKIE);
}
Your Question:
So if I undertsand correctly you want to know what is the function doing in the line
$data[clean($key)] = clean($value);
The Answer:
See the prime purpose of the function is to remove slashes from string with php's stripslashes method.
If the input item is an array then it tries to clean the keys of the array as well as the values of the array by calling itself on the key and value.
In php arrays are like hashmaps and you can iterate over the key and value both with foreach loop like following
foreach ($data as $key => $value) {....}
So if you want to summarize the algorithm in your code snippet it would be as under
Check if the input is array. If it is not then go to step 4
For each item of array clean the key and value by calling clean method on it (Recursively)
Return the array
clean the input string using stripslashes method
5 return the cleaned input
From my understanding it's not cleaning the key but creates a new element with a clean key while the uncleaned key remains.
$a['foo\bar'] : val\ue
becomes
$a['foo\bar'] : val\ue
$a['foobar'] : value
Someone correct me if im wrong.
Maybe you'll understand the code better if it's put this way:
foreach ($data as $key => $value) {
$key = clean($key); // Clean the key, the
$value = clean($value); // Clean the value
$data[$key] = $value; // Put it in the array that will be returned
}
Assuming you have an array like this:
$_POST = array(0 => 'foo', 1 => array('bar' => 'baz'));
the following will happen:
Call clean($_POST);
call clean 0
call clean 'foo'
$return[0] = 'foo'
call clean 1
call clean 'bar'
call clean 'baz'
$return[1] = array('bar' => 'baz');
You should probably read this: http://www.codewalkers.com/c/a/Miscellaneous/Recursion-in-PHP/
The main purpose of the function is to clean an associative array or a single variable. An associative array is an array where you define keys and values for that keys; so are special arrays used in PHP like $_GET $_POST and so on.
The meaning of "cleaning" is to check whether magic quotes are active - this causes some characters in these arrays to be escaped with backslashes when you post dynamic data to a PHP page.
$_GET["Scarlett"] = "O' Hara" becomes with magic quotes $_GET["Scarlett"] = "O\' Hara"
So if magic quotes are active, the function takes care of this, and slashes are stripped so that the strings retain their correct, not escaped value.
The algorithm checks if the data passed to the function is an array, if not it cleans directly the value.
$string = "Escapes\'in\'a string";
clean($string);
is it an array? No. Then return stripslashes(my data)
$array = array("key\'with\'escapes"=>"value\'with\'escapes", "another\'key"=>"another value");
clean($array)
is it an array? Yes. So cycle through each key/value pair with foreach, take the key and clean it like the first example; then take the value and do the same and put the cleaned versions in the array.
As you see the function has two different behaviours differentiated by that "if" statement.
If you pass an array, you activate the second behaviour that in turns passes couples of strings, not arrays, triggering the first behaviour.
My thought is that this function doesn't work properly, though. Anyone got the same sensation? I have it not tested yet but it seems it's not "cleaning" the key/values in the sense of replacing them, but adds the cleaned versions along the uncleaned ones.

PHP - Variable Variables & array_merge() - not working

I have a bunch of arrays, which are stored in different variables like $required, $reserved, etc...
I would like to allow (inside a function) an array of options to be passed (like $options = array('required', 'reserved')), and that array would then be used to define which arrays to merge together and return at the end of the function.
So, I have this code in part of the function, that should grab all the options and merge the arrays, using variable variables to get the arrays from the strings passed in the options array):
$array = array();
foreach ($options as $key) {
$array_to_merge = ${$key};
array_merge($array, $array_to_merge);
}
return $array;
However, when I return the $array, it shows 0 items. If I print_r($array_to_merge);, I actually get the entire array as I should.
Does array_merge() simply not work with variable variables, or am I missing something here...?
array_merge returns the merged array, you're not assigning that return value to anything and thus it is being lost.
$array = array_merge($array, $array_to_merge);
should fix your problem.
If I read it right you can also simplify your code (replaces the loop) to just:
$array = call_user_func_array("array_merge", compact($options));
compact replaces the variable variable lookup and gets the list of arrays. And in effect there is only one array_merge call necessary.

php get 1st value of an array (associative or not)

This might sounds like a silly question. How do I get the 1st value of an array without knowing in advance if the array is associative or not?
In order to get the 1st element of an array I thought to do this:
function Get1stArrayValue($arr) { return current($arr); }
is it ok?
Could it create issues if array internal pointer was moved before function call?
Is there a better/smarter/fatser way to do it?
Thanks!
A better idea may be to use reset which "rewinds array's internal pointer to the first element and returns the value of the first array element"
Example:
function Get1stArrayValue($arr) { return reset($arr); }
As #therefromhere pointed out in the comment below, this solution is not ideal as it changes the state of the internal pointer. However, I don't think it is much of an issue as other functions such as array_pop also reset it.
The main concern that it couldn't be used when iterating over an array isn't an problem as foreach operates on a copy of the array. The PHP manual states:
Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself.
This can be shown using some simple test code:
$arr = array("a", "b", "c", "d");
foreach ( $arr as $val ){
echo reset($arr) . " - " . $val . "\n";
}
Result:
a - a
a - b
a - c
a - d
To get the first element for any array, you need to reset the pointer first.
http://ca3.php.net/reset
function Get1stArrayValue($arr) {
return reset($arr);
}
If you don't mind losing the first element from the array, you can also use
array_shift() - shifts the first value of the array off and returns it, shortening the array by one element and moving everything down. All numerical array keys will be modified to start counting from zero while literal keys won't be touched.
Or you could wrap the array into an ArrayIterator and use seek:
$array = array("foo" => "apple", "banana", "cherry", "damson", "elderberry");
$iterator = new ArrayIterator($array);
$iterator->seek(0);
echo $iterator->current(); // apple
If this is not an option either, use one of the other suggestions.

Categories