I was wondering...is it possible to use a value from an array which is currently being declared? Something like:
$a = array(
'foo' => 'value',
'bar' => $a['foo']
);
This is only a simple example. It would be pretty useful doing this, since it frees you from doing extra manipulation after the array declaration.
No, you can't, but you can do something like :
$a = array(
'foo' => ($val = 'value'),
'bar' => $val
);
No. $a['foo'] will only be available after the assignment completes entirely.
Related
This is an array,
$array = array(
'one' => 1,
'two' => 2,
'three' $array['one'] + $array['two']
);
It's get an error,
why?
Because $array does not exist before the end of your declaration. You simply cannot define an array on such a recursive manner since you refer to a non-existing resource.
This is a working variant. Indeed, not very convenient, but working:
<?php
$array = [
'one' => 1,
'two' => 2
];
$array['three'] = $array['one'] + $array['two'];
var_dump($array);
The output obviously is:
array(3) {
'one' =>
int(1)
'two' =>
int(2)
'three' =>
int(3)
}
The only really elegant way around this requires quite some effort:
You can implement a class implementing the ArrayAccess interface. That allows you to implement how the properties should be defined internally (for example that sum), whilst still allowing to access these properties via an array notation. So no difference to an array at runtime, only when setting up the object. However this is such a huge effort that I doubt it is worth it in >99% of the cases.
You're using a variable which is being declared, its value value is not know yet. Here is how you should write it:
$array = array(
'one' => 1,
'two' => 2,
);
$array['tree'] = $array['one'] + $array['two'];
echo $a['b']['b2'];
What does the value in the brackets refer to? Thanks.
This is an array.
what you are seeing is
<?php
$a = array(
'b' => array(
'b2' => 'x'
)
);
So in this case, $a['b']['b2'] will have a value of 'x'.
This is just my example though, there could be more arrays in the tree. Refer to the PHP Manual
Those are keys of a multidimensional array.
It may refer to this array:
$a = array(
"a" => array(
"a1" => "foo",
"a2" => "bar"
),
"b" => array(
"b1" => "baz",
"b2" => "bin"
)
)
In this case, $a['b']['b2'] would refer to 'bin'
This refers to a two dimensional array, and the value inside the bracket shows the key of the array
That means the variable $a holds an array. The values inside of the brackets refer the array keys.
$a = array('b' => 'somevalue', 'b2' => 'somevalue2');
In this case echo'ing $a['b'] would output it's value of 'somevalue' and $a['b2'] would output it's value of 'somevalue2'.
In your example, it's refering to a multi-dimensional array (an array inside of an array)
$a = array('b' => array('b2' => 'b2 value'));
where calling b2 would output 'b2 value'
Sorry if my answer is too simplistic, not sure your level of knowledge :)
$a is an array, a list of items. Most programming languages allow you to access items in the array using a number, but PHP also allows you to access them by a string, like 'b' or 'b2'.
Additionally, you have a two-dimensional array there - an array of arrays. So in that example, you are printing out the 'b2' element of the 'b' element in the $a array.
Usually I can get away with using something like:
$a = ($condition)? array(1,2,3) : '';
But now I have a method that accepts a multidimensional array and I must pass or not pass one of the arrays conditionally.
$this->mymethod(
'myarrays'=> array(
array('key' => 'lang_code'),
array('key' => 'lang_description'),
array('key' => 'lang_direction'),
($mycondition==true)? array('key' => 'lang_export') : ),
)
);
Basically, the issue is with the last array passed. And more specifically the ELSE statement in the ternary If operator. It seems that I can't pass simply a blank space after the : and I can't pass anything else like FALSE or '' (empty string), because later on in the code the foreach that runs through this array gives errors.
My question is:
How to pass a parameter to a function/method based on a condition?
array_filter(array(
array('key' => 'lang_code'),
array('key' => 'lang_description'),
array('key' => 'lang_direction'),
$mycondition ? array('key' => 'lang_export') : null),
));
This will remove the null
Use:
$mycondition? array('key' => 'lang_export') : null
Now, you could simply run it through array_filter(..), to remove that NULL element.
Aim for readability, not for how can you type less. The ternary operator is great because in certain cases it increases readability. This is certainly not that case.
Be nice to the people reading your code later, including yourself.
Here is an example (comments are the thoughts of the future reader):
//OK, so here we have an array
$array = array(
array('key' => 'lang_code'),
array('key' => 'lang_description'),
array('key' => 'lang_direction'),
);
//So the array can have one more element based on this condition
if ($mycondition) {
$array[] = array('key' => 'lang_export');
}
//And then we pass this array to the method
$this->mymethod(array('myarrays' => $array));
You are free to use variables and don't have to write all your code in one statement (well, I must admit I thought that was cool earlier).
You could evaluate the condition before the function call, e.g. with a helper-function:
function evaluate_condition (array $mandatory, array $optional, $condition) {
if (true === $condition) {
$mandatory[] = $optional;
}
return $mandatory;
}
$this->mymethod(
'myarrays'=> $this->evaluate_condition(
array(
array('key' => 'lang_code'),
array('key' => 'lang_description'),
array('key' => 'lang_direction')
),
array('key' => 'lang_export'),
$mycondition
)
);
It's pretty handy in JS to create objects like this:
test = { foo : { bar : "hello world" }, bar2 : "hello world 2" }
and then use them like:
test.foo.bar
test.bar2
Is there anything like this in PHP without declaring classes?
It's called associative arrays.
Example (note: the indentation is for layout purposes):
$test = array(
'foo' => array(
'bar' => 'hello world'
),
'bar2' => 'hello world 2'
);
$test['foo']['bar'];
$test['bar2'];
This is equivalent to the following Javascript code:
var test = {
'foo': {
'bar': 'hello world',
},
'bar2': 'hello world 2'
};
As an alternative, you can use the pre-declared StdClass.
$test = new StdClass;
$test->foo = new StdClass;
$test->foo->bar = 'hello world';
$test->bar2 = 'hello world 2';
which would be written in JavaScript as:
var test = new Object;
test.foo = new Object;
test.foo.bar = 'hello world';
test.bar2 = 'hello world 2';
(note: new Object is the same as {} in Javascript)
stdClass allows you to create (essentially) typeless objects. For example:
$object = (object) array(
'name' => 'Trevor',
'age' => 42
);
As shown here, the fastest way to create a stdClass object is to cast an associative array. For multiple levels, you just do the same thing again inside like this:
$object = (object) array(
'name' => 'Trevor',
'age' => '42',
'car' => (object) array(
'make' => 'Mini Cooper',
'model' => 'S',
'year' => 2010
)
);
Another method is to convert the associative array to an object afterwards with a recursive function. Here's an example.
function toObject(array $array) {
$array = (object) $array;
foreach ($array as &$value)
if (is_array($value))
$value = toObject($value);
return $array;
}
// usage:
$array = // some big hierarchical associative array...
$array = toObject($array);
This is useful when you're not the one making the associative array.
Unfortunately, even though PHP 5.3 supports anonymous methods, you cannot put an anonymous method into a stdClass (though you can put one into an associative array). But this isn't too bad anyway; if you want functionality in it, you really should create a class instead.
You can use a StdClass object or an ArrayObject which are included in php (though the latter requires that you have SPL installed). Though unless you need to access the values specifically with the -> operator its more efficient to just use an associative array instead.
I think what you are looking for is an Associative Array
$test["foo"]["bar"]
http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=keyed+arrays
The closest thing would be arrays.
$test = array(
'foo' => array('bar' => 'hello world'),
'bar2' => 'hello world 2',
);
echo $test['foo']['bar'];
Technically, no. However if you are creating a data object (ie no methods), you could technically write a JSON string and use
$obj = json_decode($obj_string);
I wouldn't recommend it however. I assume there would be significant speed loss.
EDIT
Though it goes without mentioning, associative arrays should be used for this instead of flat data objects.
The only reason to do that is if you wish to pass data back to a JavaScript function with JSON. In that case, use json_encode on the array. Otherwise, just keep it as an array, as there's not reason to encode it and then decode it just so it looks like JavaScript.
Try this way: https://github.com/ptrofimov/jslikeobject
Author implemented JS-like objects, you can even access properties from functions via $this pointer.
But perhaps it is not so good to use such objects instead of usual ones.
$a = array(
'a'=> 123,
'b'=> 334,
'c'=> 7853
);
echo json_encode($a);
This will be the result: {"a":123,"b":334,"c":7853}
I have an api listener script which takes in get parameters. But I seem to be having issues when users tend to pass mixed case variable names on the parameters.
For example:
http://mylistenerurl.com?paramName1=Hello¶mname2=World
I need my listener to be flixible in such a way that the variable names will be interpreted case-insensitively or rather still all in lower case like after I process the query string on some function, they are all returned as lower-cased variables:
extract(someFunction($_GET));
process($paramname1, $paramname2);
Can anybody shed some light on this?
*much appreciated. thanks!
This should do the trick:
$array_of_lower_case_strings = array_map( "strtolower", array( "This Will Be ALL lowercase.", ... ) );
So in your case:
$get_with_lowercase_keys = array_combine(
array_map( "strtolower", array_keys( $_GET ) ),
array_values( $_GET )
);
One thing I'll mention is you should be VERY careful with extract as it could be exploited to allow unexpected variables to be injected into your PHP.
Apply to your global variables ($_GET, $_POST) when necessary:
e.g. setLowerCaseVars($_GET); in your case
function setLowerCaseVars(&$global_var) {
foreach ($global_var as $key => &$value) {
if (!isset($global_var[strtolower($key)])) {
$global_var[strtolower($key)] = $value;
}
}
}
Edit: Note that I prefer this to using array_combine because it will not overwrite cases where the lower-case variable is already set.
PHP has had a native function (array_change_key_case()) for this task since version 4.2 to change the case of first level keys. To be perfectly explicit -- this function can be used to convert first level key to uppercase or lower case BUT this is not a recursive function so deeper keys will not be effected.
Code: (Demo)
parse_str('paramName1=Hello¶mname2=World&fOo[bAR][BanG]=boom', $_GET);
var_export($_GET);
echo "\n---\n";
$lower = array_change_key_case($_GET);
var_export($lower);
Output:
array (
'paramName1' => 'Hello',
'paramname2' => 'World',
'fOo' =>
array (
'bAR' =>
array (
'BanG' => 'boom',
),
),
)
---
array (
'paramname1' => 'Hello', # N changed to n
'paramname2' => 'World',
'foo' => # O changed to o
array (
'bAR' => # AR not changed because not a first level key
array (
'BanG' => 'boom', # B and G not changed because not a first level key
),
),
)