I have a very simple array where I want to be able to add settings as simple as possible. In my case, if I don't need a second value, I don't need to add it.
Code
$settings = [
'my_string',
'my_array' => 'hello'
];
print_r($settings);
Result
The problem with my approach is that my_string is seen as a value and the key 0 is added.
Array
(
[0] => my_string
[my_array] => hello
)
I could check if the key is a number and in that case figure out that I don't use a second value.
Is there a better approach?
I'm aware of that I can use multiple nested arrays but then simplicity is gone.
The way you've written it, you wouldn't be able to access the value 'my_string' without some kind of key. There is always a key for any value, and if you don't specify values, PHP generates them as though they were indices in an actual array (PHP 'arrays' are actually dictionaries/maps/etc. that have default behavior in the absence of a specified key).
$settings = [
'name' => 'my_string',
'my_array' => 'hello'
];
If you don't want to use $settings[0] -- and I wouldn't want to either -- you should probably decide on a name for whatever 'my_string' is supposed to be and use that as its key.
Related
My system is centos 7.4 with PHP 5.4
$s='a:91:{s:13:"spotsviewvars";s:7:"1916.74";s:13:"100000T18vars";N;s:17:"100000T18S106vars";s:7:"1746.95";s:17:"100000T18S107vars";s:4:"4.49";s:17:"100000T18S108vars";s:4:"8.29";s:17:"100000T18S109vars";s:4:"4.38";s:17:"100000T18S110vars";s:3:"5.4";s:17:"100000T18S111vars";s:4:"3.88";s:17:"100000T18S112vars";s:4:"3.49";s:17:"100000T18S113vars";s:4:"5.55";s:17:"100000T18S114vars";s:4:"3.58";s:17:"100000T18S115vars";s:3:"5.5";s:17:"100000T18S116vars";s:5:"10.39";s:17:"100000T18S117vars";s:4:"6.52";s:17:"100000T18S118vars";s:4:"6.09";s:17:"100000T18S119vars";s:3:"6.7";s:17:"100000T18S120vars";s:4:"4.18";s:17:"100000T18S121vars";s:5:"14.81";s:17:"100000T18S122vars";s:3:"3.9";s:17:"100000T18S123vars";s:4:"4.93";s:17:"100000T18S124vars";s:4:"4.06";s:17:"100000T18S125vars";s:4:"5.03";s:17:"100000T18S126vars";s:4:"5.73";s:17:"100000T18S127vars";s:4:"3.13";s:17:"100000T18S128vars";s:3:"7.2";s:17:"100000T18S129vars";s:4:"7.03";s:17:"100000T18S130vars";s:4:"3.81";s:17:"100000T18S131vars";s:3:"7.4";s:17:"100000T18S132vars";s:4:"7.82";s:17:"100000T18S133vars";s:4:"3.96";s:13:"100000T19vars";N;s:17:"100000T19S134vars";N;s:17:"100000T19S135vars";N;s:17:"100000T19S136vars";N;s:17:"100000T19S137vars";s:5:"12.54";s:17:"100000T19S138vars";N;s:17:"100000T19S139vars";N;s:17:"100000T19S140vars";N;s:17:"100000T19S141vars";N;s:17:"100000T19S142vars";N;s:17:"100000T19S143vars";N;s:17:"100000T19S144vars";N;s:17:"100000T19S145vars";N;s:17:"100000T19S146vars";N;s:17:"100000T19S147vars";N;s:17:"100000T19S148vars";N;s:17:"100000T19S149vars";N;s:13:"100000T18S106";s:2:"A2";s:13:"100000T18S107";s:2:"A2";s:13:"100000T18S108";s:2:"A2";s:13:"100000T18S109";s:2:"A2";s:13:"100000T18S110";s:2:"A2";s:13:"100000T18S111";s:2:"A2";s:13:"100000T18S112";s:2:"A2";s:13:"100000T18S113";s:2:"A2";s:13:"100000T18S114";s:2:"A2";s:13:"100000T18S115";s:2:"A2";s:13:"100000T18S116";s:2:"A2";s:13:"100000T18S117";s:2:"A2";s:13:"100000T18S118";s:2:"A1";s:13:"100000T18S119";s:2:"A2";s:13:"100000T18S120";s:2:"A1";s:13:"100000T18S121";s:2:"A1";s:13:"100000T18S122";s:2:"A2";s:13:"100000T18S123";s:2:"A2";s:13:"100000T18S124";s:2:"A2";s:13:"100000T18S125";s:2:"A2";s:13:"100000T18S126";s:2:"A1";s:13:"100000T18S127";s:2:"A2";s:13:"100000T18S128";s:2:"A1";s:13:"100000T18S129";s:2:"A1";s:13:"100000T18S130";s:2:"A2";s:13:"100000T18S131";s:2:"A2";s:13:"100000T18S132";s:2:"A1";s:13:"100000T18S133";s:2:"A2";s:13:"100000T19S134";N;s:13:"100000T19S135";N;s:13:"100000T19S136";N;s:13:"100000T19S137";s:0:"";s:13:"100000T19S138";N;s:13:"100000T19S139";N;s:13:"100000T19S140";N;s:13:"100000T19S141";N;s:13:"100000T19S142";N;s:13:"100000T19S143";N;s:13:"100000T19S144";N;s:13:"100000T19S145";N;s:13:"100000T19S146";N;s:13:"100000T19S147";N;s:13:"100000T19S148";N;s:13:"100000T19S149";N;}';
$s_array=unserialize($s);
var_dump($s_array);
$s_json=json_encode($s_array,JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_UNESCAPED_UNICODE);
var_dump($s_json);
You will notice strange result when run above PHP script.
$s_array is array,json_encode result should be something like [],but result is {}.
What's the problem?
You appear to just have been confused by differences in terminology.
In PHP an "array" can either be an indexed array (in which you have a sequence of values) or an associative array (in which you have name => value pairs).
In JSON a sequence of values is stored in an array, and a set of name => value pairs is stored in an object.
Since you have name => value pairs in your data, you get an object when converting it to JSON.
For comparison:
$indexed_array = [ "foo", "bar", "baz" ];
$associative_array = [ "foo" => "A", "bar" => "B", "baz" => "C" ];
print json_encode($indexed_array);
print "\n";
print json_encode($associative_array);
The code is working exactly as it should.
What you've got there is an associative array - i.e. each entry has a name (like "spotsviewvars", or "100000T18vars" rather than a numeric index (like 0 or 1). It's effectively a set of key/value pairs.
So in order to preserve that information when encoding as JSON, it has to be turned into an object instead - JSON has no concept of associative arrays. The only possible JSON representation which keeps both the key (e.g. "spotsviewvars") and the associated value (e.g. "1916.74") is an object.
If you turned it into a plain array you'd lose the key information, which I would assume is important. Every value would just have a numeric index to hold it instead, and you wouldn't know what its original meaning was.
It seems that all my questions are so basic that I can't find answers for them anywhere, probably because all the guides assume you have at least some basic knowledge. Anyway, on to my question...
With regard to PHP, are keys inherent to arrays? In other words, if I get data from a form that gives me a set of values in the $_POST array, are there keys assigned to the values by default, or do keys only exist if they are created explicitly? I am assuming there are no keys if I don't create them, but I suspect that there could be numerical keys assigned to each value automatically.
In the most basic sense - "key" is just an instruction for computer how to find required value in the array. So key is like an address of value cell. And you don't find a house in a city without an address - so you will likely don't find value in the array without a key either. Most programming languages supports plain arrays, where key is just an integer - 0,1,2,3,... Consider this array's element layout in memory:
Element index/key: 0 1 2 3 4
Value: A B C D E
And when you ask for a computer - give me array[3] element - it knows that
it needs to look at memory cell array_byte_offset_in_ram + size_in_bytes_of(array_element) * 3
Same instruction expressed in human language will be "find where first array element is stored in memory and jump from it forward in memory by 3x memory amount which is needed to store 1 array element". By doing this algo finds your cell and fetches your value D.
For arrays of arbitrary keys, when key can be any string - is another story. But idea remains the same - from the key computer should deduce How to find required element cell in memory. Usually this done by translating arbitrary string keys into integer hash values. Then sorting these hashes and performing binary search algorithm to find integer-index of required hash value. Last step is to pass index found into another plain array where your real values are stored.
Consider this array:
Element key: 'ABC' 'EFG' 'CDE'
Value: a b c
There are many ways to calculate hashes, but for simplicity consider stupid hash function
hash(string) = sum(ascii_values_of_chars_in_string)
So we have following hash table:
hash('ABC') = ord('A')+ord('B')+ord('C')
hash('EFG') = ord('E')+ord('F')+ord('G')
hash('CDE') = ord('C')+ord('D')+ord('E')
After sorting hashes we generate and save such hash array:
hash[0] = 198
hash[1] = 204
hash[2] = 210
Now we can save array values into another plain array where integer index should be the same as hash array index of saved hash(key) function output =>
value[0] = 'a'
value[1] = 'c'
value[2] = 'b'
Now when you request - give me array['EFG'] value - computer calculates key 'EFG' hash which is 210. Then by employing binary search algo finds 210 value in hash table and deduces that it's index in hash table is 2. So it jumps to value table at index 2 by using above described technique of plain arrays and fetches resulting value of 'b' which will be returned to you.
These are the main principles of array keys. Of course there are much more things under the hood - such as hash collisions and etc. But at this point you don't need more complexities as for now. Simply keep in mind that at most bare-bones of computer architecture - there is only plain numbers and math operating on them - no fancy things like "strings"/"objects" and another cosmos :-)
If you assign an existing array to a new variable, it will be like you copied that array to that variable.
So let's say you have:
$initialArray = ["test1" => "My First Test", "test2" => "My Second Test"];
If you initialize a new variable and say it should be equal to the array you desire:
$aNewArray = $initialArray;
Your new array will be exactly like the one you said for it to copy;
Also, if you change $initialArray after you copied to the $aNewArray, your changes will only affect the variable you change, keeping your $aNewArray with the same data before you changed.
Now, if you just set a few variables into an array without specifying keys to access them, it will automatically link them by numeric index:
$arrayWithoutSpecificKeys = ["one", "two", "three"];
print_r($arrayWithoutSpecificKeys);
This output will be:
array (
0 => "one",
1 => "two",
2 => "three"
);
Never forget array start with index 0;
This means if you assign $_POST to a variable, it will inherit the key => values transmitted.
In your form you will name you inputs like this:
<input type="text" name="surname" .../>
Your $_POST variable will have an array with whatever information you set in your input, and link them as bellow:
["surname" => "<your typed value>"]
Then again, if you copy the $_POST to a variable, that variable will inherit all the content that $_POST contains;
Hope it helped!
An array in PHP is actually an ordered map. A map is a type that
associates values to keys.
PHP Documentation
This means that you can only have one index, however you need to be aware that arrays implement an internal pointer, and technically you can iterate the array by sequentially hopping through each array entry. This is what foreach does for you. You can check next documentation for more details.
In case if you don't supply keys when creating an array, then keys will be assigned automatically. Array created by the following line of code will assign index (key) for each of its elements (starting from 0):
$array = array("foo", "bar", "hello", "world");
I have PHP $_SESSION arrays that have an undefined amount of elements. Is it possible to initialise all the values to 0, or do I have to check whether the value is NULL and then set to 0 every time I check a value?
Edit: I'm sorry for the vagueness of my question.
I have an undefined amount of levels, and I'd like to store all the scores of each level in that array. Currently my amount of levels is fixed, so I am currently just writing:
$_SESSION['totals'] = array(0,0,0,0,0);
And then when adding manipulating the data, I simply increment/add a certain amount to that element.
Now I'd prefer to have the same ease of directly incrementing/adding values to certain elements without needing to check whether a value is NULL or something like that...
Edit 2: edited my code as follows:
$_SESSION['totals'] = array();
if(array_key_exists($row['level']-1,$_SESSION['totals'])){
$_SESSION['totals'][$row['level']-1]++;
}else{
$_SESSION['totals'][$row['level']-1] = 1;
}
And it seems to work. Thanks fellas!
You can use array_fill_keys function to fill an array with specified value for defined keys:
$keys = array('foo', 'bar', 'baz');
$output = array_fill_keys($keys, 0);
Defining an array with initial values is defining an array with a length. This does not prevent you from adding or removing elements from the array:
// initial array
$myArray = [0, 0, 0, 0];
print_r($myArray); // would output Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 0)
$myArray[] = 1;
print_r($myArray); // would output Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 0 [4] => 1 )
$_SESSION contains only what you put into it. Just make sure you add 0 instead of null the first time you add something.
If you need to do this later, I think your design might be bad. But anyway, $_SESSION is like a normal array, so you can just use PHP's array function to traverse the array and check or change each value.
PHP arrays aren't really arrays you might know from other languages. They really are more like linked lists with hash access.
What this means is: You either know all the string array indices you want to use, and either make sure they exist, or you check their existence every time you access them which might fail.
For numeric indices, the same thing applies. You might have an array with indices 1, 2 and 4 present, but if you run over it with only a for loop, you will trigger a notice when accessing the nonexistant element 3.
Use foreach loops whenever you want to iterate arrays. Check with isset() whenever you want to document that the array value might not be present. Don't do it if you know or assume that the array element MUST be present - if not, you get the notice as a reminder that your code is working on a data structure that is NOT what you thought it is. Which actually is a good thing. Then fix it. :)
Your best bet would be to abstract your session stuff by creating facade methods, or getters and setters around the session variables rather than access them directly. This way you can return a default value if the one you're after doesn't exist.
I've used array_key_exists() to check if the index is set. If it is not, I display 0 or add store a certain value in that field, else I show the value of that index or add certain value to that field.
Credit to Sven for bringing that up.
to check what u have in your sessions, loop tru it. not sure if this is what u are asking.
foreach($_SESSION as $x=>$y)
{
if(empty($x)) { //do something }
}
I have the following array and i want to access the value of a specified element with twig.
numbers => Array ([01234567] => Array ( [0] => 9876543210 [1] => 8765432109 [2] => 0000000000))
I know there is only one entry in numbers, so I want to access the array with the key 01234567 directly.
Even tough numbers|keys[0] does return the correct key, I can't use it like numbers[numbers|keys[0]] to get the array. I also tried the attribute(array, item) function, but i didn't got it to work.
Is it possible to access it directly or do I need to use loops?
You have found a probably undocumented "feature" of Twig. If you check the source code, twig tries to determine if the given key is numeric, or not. It does this check with the ctype_digit function, which checks if a variable contains only numeric characters.
The example in your question contains an array key, which meets this conditions: it contains only numbers. Unfortunately, it also starts with a zero, which is removed when the string is converted into an integer.
I'm not exactly sure that this is intended behavior, so you may try to report this example as a bug.
For the current twig implementation, because everything except the loop construct uses the getAttribute function, you have no other choice but to use a for loop.
I'm trying to create an array of bar objects in php which consist of seven different attributes. The code I am using for this array is as follows:
$barsArray = array();
for($i = 0; $i < count($barNameArray); $i++)
{
$barsArray[] = array('BarName' => $barNameArray[$i], 'first' => $firstCover[$i], 'timeFirst' => $firstTimes[$i],
'second' => $secondCover[$i], 'timeSecond' => $secondTimes[$i],
'third' => $thirdCover[$i], 'timeThird' => $thirdTimes[$i]);
}
I have checked to make sure that all the other arrays are as I intend them. I just need to get this into one array of objects. Is this method completely off? Also, If I wanted to test to make sure that the correct objects are in the correct locations in a multidimensional array, how would I go about do that?
Thanks!
That code looks fine (although you may want to cache the count instead of performing it repeatedly).
I can't say for sure, not knowing your greater purpose, but you may want to make $barsArray an associative array by the bar name. To do that, use $barsArray[$barNameArray[$i]] =, instead of $barsArray[] = (and of course remove the BarName property). This would not keep it in the original ordering, but would make getting a particular bar easier.
You can get an element from $barsArray like so: $barsArray[3]['first'] (or $barsArray['some_bar_name']['first'] if you change it to an associative array).