In PHP 7, I want only arrays to be in the parameters, but what is the difference between:
function exampleA(array $a, array $b)
{
}
and
function exampleB($a = array(), $b = array())
{
}
Not sure which I should be using.
The comments are good but I guess we need an answer.
exampleA() using array $a forces the arguments to be of type array and if not it throws a catchable error:
exampleA();
exampleA(1, 'A');
Both yield:
Catchable fatal error: Argument 1 passed to exampleA() must be of the type array, none given, called in file on line X and defined in file on line X
Whereas in exampleB() using $a = array():
function exampleB($a = array(), $b = array())
{
var_dump(get_defined_vars());
}
Sets default values to empty arrays when no values are supplied:
exampleB();
Yields:
array(2) { ["a"]=> array(0) { } ["b"]=> array(0) { } }
However, when values are supplied those values are used regardless of type:
exampleB(1, 'A');
Yields:
array(2) { ["a"]=> int(1) ["b"]=> string(1) "A" }
Related
My goal is very simple, I want to parse the $GLOBALS variable in JSON (to log it). According to this Stackoverflow post, https://stackoverflow.com/a/23176085/1369579, I have to remove the recursive variable.
The following code works:
<?php
$global_array = $GLOBALS;
$index = array_search('GLOBALS',array_keys($global_array));
$json = json_encode(array_splice($global_array, $index, $index-1));
var_dump($json);
?>
It returns string(59) "{"GLOBALS":{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}}" (in http://sandbox.onlinephpfunctions.com)
But I have to use an intermediate variable to store the array_splice result. When I do this, I doesn't works:
<?php
$global_array = $GLOBALS;
$index = array_search('GLOBALS',array_keys($global_array));
$splice_result = array_splice($global_array, $index, $index-1);
var_dump(json_encode($splice_result));
?>
The result is bool(false) and the json_last_error_msg() returns Recursion detected.
What the difference between the two versions? I really don't understand. For me foo(bar()) is the exactly the same code than $bar = bar(); foo($bar)…
I just understood my problem, the call of array_splice remove the $GLOBALS variable… but I still don't understand why.
I tried to put my code into a function, because I thought my problem was to put the code directly in the global scope:
<?php
function globalWithoutGlobals() {
$global_array = $GLOBALS;
$index = array_search('GLOBALS',array_keys($global_array));
array_splice($global_array, $index, 1);
return $global_array;
}
var_dump(json_encode(globalWithoutGlobals()));
var_dump(json_encode(globalWithoutGlobals()));
/* returns
# First call: success,
string(47) "{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}"
# Second call : wtf ?!!
<br />
<b>Notice</b>: Undefined variable: GLOBALS in <b>[...][...]</b> on line <b>4</b><br />
*/
It's still very weird for me, the $global_array should be changed, not the $GLOBALS. To test this behaviour, I did the same thing on others arrays (with recursion too):
<?php
// Looks like $GLOBALS (with recursive element)
$globals_array = ["foo" => "bar"];
$globals_array['GLOBALS'] = &$globals_array;
$copy = $globals_array;
$index = array_search('GLOBALS', array_keys($copy));
array_splice($copy, $index, 1);
var_dump($globals_array);
var_dump($copy);
/* return:
array(2) {
["foo"]=>
string(3) "bar"
["GLOBALS"]=>
&array(2) {
["foo"]=>
string(3) "bar"
["GLOBALS"]=>
*RECURSION*
}
}
array(1) {
["foo"]=>
string(3) "bar"
}
*/
It returns the expected output, so why the behaviour is not the same with $GLOBALS ? 😩
To resolve my issue, I changed my approach and I stopped used array_splice, instead I just do a naive implementation with a foreach on the $GLOBALS and it works like expected:
<?php
function globalWithoutGlobals() {
$result = [];
foreach ($GLOBALS as $key => $value) {
if ($key !== 'GLOBALS') {
$result[$key] = $value;
}
}
return $result;
}
var_dump(json_encode(globalWithoutGlobals()));
var_dump(json_encode(globalWithoutGlobals()));
/* it returns:
string(47) "{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}"
string(47) "{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}"
*/
If someone know why the behaviour is different between my two first examples above. I'm curious to understand 😊
I was trying to get a clear difference between methods call_user_func() and call_user_func_array() when I stumbled upon a difference in return types that wasn't apparent to me before.Consider the class Test with a method dnd($t):
class Test {
function dnd($t) {
echo "<pre>";
var_dump($t);
echo "</pre>";
}
}
Instantiate:
$obj = new Test();
$params = [33,22,'fff'];
Now calling by call_user_func method
call_user_func([$obj,'dnd'], $params);
This results in:
array(3) {
[0]=>
int(33)
[1]=>
int(22)
[2]=>
string(3) "fff"
}
While call_user_func_array:
call_user_func_array([$obj,'dnd'], $params);
yields:
int(33)
Why this variation and what impact does it have on parameters passed to functions or function calls that rely on parameters?
call_user_func([$obj,'dnd'], $params)
This resolves to
$obj->dnd(array(33, 22, 'fff'))
while
call_user_func_array([$obj,'dnd'], $params)
resolves to
$obj->dnd(33, 22, 'fff')
In the second parameter call_user_func receives the 'arguments' separately.
So our only argument is the array.
$t = [33,22,'fff']
The second parameter call_user_func_array receives the 'arguments' in the form of an array and sends them to the desired function.
As a result, the first array index is used as the only argument.
$t = int(33) // int(22) and 'fff' are the second and third arguments of the dnd() method (not defined here)
I'm trying to implement a DataTable class in php which will be basically a table to contain data just like an sql table and will be made of array()
The class is defined as followed:
class DataTable{
protected static $tabela; // table
//columns and strips, each column point to a strip
public function __construct($colunas, $faixas) {
$this->tabela = array();
$this->constroiDt($colunas, $faixas); //builds the table
}
public function getRows($where){
// todo
}
public static function getTabela(){
return $this->tabela;
}
private function constroiDt($colunas, $faixas){
if(count($colunas)!= count($faixas)){
$this->tabela = null;
return;
}
$i=0;
foreach($colunas as $cl){
$this->tabela = array_merge($this->tabela, array($cl => $faixas[$i]));
$i += $i + 1;
}
// the result will be an array like ('col1' => ('val1','val2'), 'col2' => ('val1','val2'))
// if I want to access a value, just type array['col1'][0] for example
}
}
Outside of the class function, when I create an example DT and try to access it, it seems that will work:
$columns = array("name", "age");
$strips = array(array("someone","another person"),array("20","30"));
$dt1 = new DataTable($columns, $strips);
var_dump($dt1); // will print:
// object(DataTable)#1 (1) { ["tabela"]=> array(2) { ["nome"]=> array(2) { [0]=> string(6) "fulano" [1]=> string(7) "ciclano" } ["idade"]=> array(2) { [0]=> string(2) "20" [1]=> string(2) "30" } } }
But then I add echo "--- " . $dt1::getTabela()['nome'][0];
It doesn't even print the ---. var_dump($dt1::getTabela()) and var_dump($dt1->getTabela()) also is blank. What is being missed here? Tried also this but didn't work.
You shouldn't use $this in a static function / for static properties as there is not necessarily an object context to use.
Instead, you should use self::$tabela everywhere instead.
Or change your variable (and the related methods...) to a "normal" protected property:
protected $tabela;
You are mixing static variables with non static accesors
i just put your code and i got a lot of errors/notices
NOTICE Accessing static property DataTable::$tabela as non static on line number 10
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
object(DataTable)#1 (1) { ["tabela"]=> array(2) { ["name"]=> array(2) { [0]=> string(7) "someone" [1]=> string(14) "another person" } ["age"]=> array(2) { [0]=> string(2) "20" [1]=> string(2) "30" } } }
FATAL ERROR Uncaught Error: Using $this when not in object context in /home/phptest/public_html/code.php70(5) : eval()'d code:20 Stack trace: #0 /home/phptest/public_html/code.php70(5) : eval()'d code(44): DataTable::getTabela() #1 /home/phptest/public_html/code.php70(5): eval() #2 {main} thrown on line number 20
Let's say I have a function which returns an object with one of it's parameters set to some certain value:
public function search($jobsdone, $date)
{
foreach ($jobsdone as $jd) {
if ($jd->date_worked == $date) return $jd;
}
}
Printing search($jobsdone, $key) yields such results:
object(JobDone)#378 (19) {
...
["attributes":protected]=>
array(9) {
["id"]=>
int(3593)
["user_id"]=>
int(13)
["object_id"]=>
int(99)
["job_id"]=>
int(130)
["date_worked"]=>
string(10) "2013-10-01"
["min_from"]=>
int(780)
["min_to"]=>
int(1080)
}
...
}
However, if I want to print out search($jobsdone, $key)->id, all I get is an error message of:
Trying to get property of non-object
What could I be missing here?
Your search function doesn't always return an object. Therefore, you get error Trying to get property of non-object whenever your search couldn't find a $jobdone object.
As title, I did it like below:
$array=array(0,1,2,3);
$result=array();
function makeArray($array,$result,$value){
$str='$result';
for ($i=0;$i<count($array);$i++){
$str.='['.$i.']';
}
$str.='="'.$value.'";';
eval($str);
return $result;
}
It can realize result when param $result is an empty array,but It report an error when $result is an array.
Error like :
Cannot use a scalar value as an array.
Anyways can realize it?
Thanks first!
Use pass by reference, not eval:
function makeArray($indexes, &$result, $value) {
$here =& $result;
foreach ($indexes as $i) {
if (!(isset($here[$i]) && is_array($here[$i]))) {
$here[$i] = array();
}
$here =& $here[$i];
}
$here = $value;
}
$array=array(0,1,2,3);
$result=array();
makeArray($array, $result, 3);
var_dump($result);
Output:
array(1) {
[0]=>
array(1) {
[1]=>
array(1) {
[2]=>
array(1) {
[3]=>
int(3)
}
}
}
}
Putting & before a function parameter means it will be passed by reference, so modifications to the variable inside the function will affect the original variable that was passed. And using =& in an assignment assigns a reference, so the target variable is an alias for the source.