When sending an HTTP POST array of text data, for example from a web page with an HTML form and text fields, if we use as the name property of the fields the following array url_alias[id] with id being a positive integer, we receive with PHP:
[url_alias] => Array
(
[2644] => url-of-product-ref-123
[1] => url-of-product-ref-224
)
how will the server (Apache Linux, for example) handle the POST data? Will it internally prepare an array with 2645 indexes, with a null pointer to all indexes except the index: 1 and the index: 2644, or will it do in other, optimized way? Is the format above correct in terms of efficiency - it is very comfortable for PHP programming, but I am afraid of memory leakages or something.
From PHP manual:
An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.
In your example it holds only two keys with one value assigned to each.
The manual has examples on how arrays in PHP behave. For example, if you set up the following array:
$array = array(
"a",
"b",
6 => "c",
"d",
);
They keys assigned will be 0, 1, 6 and 7:
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
}
Please read the manual to learn more.
UPDATE
You are also asking how arrays are sent over HTTP. They (arrays) are not. According to W3C specification defined here:
The form data set is then encoded according to the content type specified by the enctype attribute of the FORM element.
Each enctype has it's own rules too long and extensive to be listed here. Read it there if you wish. The thing is, when PHP receives the encoded data, it automatically decodes indexed form variable names.
So, to wrap it up, the form data is encoded, sent to PHP and the decoding process is on PHP side.
Related
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");
Lets begin with two small tests:
$original = [0 => 'a', 1 => 'b'];
var_dump((json_decode(json_encode($original))));
returns
array(2) { // array
[0]=> // integer like original
string(1) "a"
[1]=> // integer like original
string(1) "b"
}
So we can see here, that assoc parameter (second parameter in json_decode function) is not set (default is false), and pair json_decode-json_encode recovers original as it should.
$original = [1 => 'a', 2 => 'b'];
var_dump((json_decode(json_encode($original))));
returns
object(stdClass)#1 (2) { // object
["1"]=> // string, instead of integer
string(1) "a"
["2"]=> // string, instead of integer
string(1) "b"
}
Here again, assoc is false, but pair json_decode-json_encode can't recover original unless we explicitly set assoc into true.
Question: I am working on a custom serialization process (different from PHP serialize and unserialize functions). I decided to use json_decode-json_encode pair and I found that I can't rely on default settings, like assoc=false. Are you aware of any other pitfalls with json_ family functions that may lead me to a problem when I won't be able to recover original data and structure?
The JSON encoding for an array looks like:
[ element, element, element, ... ]
As you can see, there are no explicit indexes, so this encoding can only be used when the array contains consecutive numeric indexes starting from 0.
Any other array is encoded as an object, and object keys are always strings in JSON. When you decode an object with json_decode() it returns a PHP object if assoc is false, an associative array if it's true.
When you go through the JSON encoding process for an object, there's no way to tell whether the original array had numeric or string indexes. They'll always become strings in JSON.
Furthermore, when you use assoc = false, and the result is an object, the properties necessarily have to be strings, because PHP objects can't have numeric property names.
When you use assoc = false you recover the original because PHP itself doesn't distinguish between numbers and numeric strings as indexes in an array. If you do:
var_dump( array('1' => 'a', 2 => 'b'));
the result is:
array(2) {
[1]=>
string(1) "a"
[2]=>
string(1) "b"
}
As you can see, PHP automatically turned the string '1' into the number 1 when creating the array.
JSON was never intended to be used to encode objects in any language without information loss. It's designed as a simple format that facilitates communication between applications that may be written in different languages. So it abstracts away many of the details, and just supports basic arrays and objects. Other formats like XML and serialize allow more precision.
I always assumed that cookies may only hold strings, but the way PHP handles cookies, it is also possible to store an array in a cookie (and I'm not talking about serialized array, but a native array). All you need to do is this:
setcookie('a[1]', 'a');
setcookie('a[2]', 'b');
var_dump($_COOKIE);
The above will produce the following (remember to execute it twice):
array(1) {
["a"]=>
array(2) {
[1]=>
string(1) "a"
[2]=>
string(1) "b"
}
}
What's going on here? Clearly we managed to store an array to a cookie, which is supposed to hold strings only. Is this a bug?
It is certainly not a bug. As a matter of fact it is documented in PHP Documentation
You may also set array cookies by using array notation in the cookie name. This has the effect of setting as many cookies as you have array elements, but when the cookie is received by your script, the values are all placed in an array with the cookie's name:
A cookie value can only be a string.
When PHP parses the cookies into $_COOKIE, certain naming conventions (i.e. cookies with names that end in [] or [something]) will cause it to represent them as an array.
I have an array of forms for a list of accessories defined, in a simpler than existing form, like so:
echo CHtml::activeCheckBox($accessory, 'bidirectional[]', array('checked'=>$accessory->bidirectional));
I do the form building this way so that I can dynamically add new rows via jQuery without having to fiddle with index positions within all the elements.
The problem I am getting is that activeCheckBox produces two fields for the sake of setting 0 in the active record. This causes problems when I come to rebuild the form, due to two entries for this element I actually convert:
array(9) { ["bidirectional"]=> array(2) { [0]=> string(1) "0" [1]=> string(1) "1" } }
To the latter entry having it owns row and so breaking all my programming.
Is there anyway to do dynamic indexes for lists of forms in Yii easily or do I have to go back to using static indexes?
By default, yii activeCheckBox generates hidden input, so when submitting form value is always set. In your case hidden inputs breaks indexes.
To keep dynamic indexes hidden inputs should be removed. Drawback of this is that you no longer have "unchecked" value. To disable uncheck value, simply set uncheckValue to null:
echo CHtml::activeCheckBox($accessory, 'bidirectional[]', array(
'checked'=>$accessory->bidirectional,
'uncheckValue' => null
));
In other programming languages the definition of arrays is something which can hold similar kind of elements. For example if I declare something like int i[] it will store integers, but in PHP a single array seems to be holding strings and numbers together.
Will the number/integer be treated as string in such type of array in PHP?
According to the PHP manual you can indeed store heterogeneous types inside a PHP "array" - scroll down to example 3.
Note that even though the example is about keys being ints or strings, the values assigned in the example are also both ints and strings, demonstrating that it is possible to store heterogeneous types.
Be aware that in the case of different-typed keys there is automatic casting involved so you may have surprising results in the case where e.g. a string contains a valid decimal representation.
Yes. A PHP array can have multiple data types in it.
Also, you should note that arrays in PHP actually are represented in the form of key-value pairs, where the elements you will input into the array are values.
You can explicitly define keys too, when entering elements into the array, but when you don't, PHP will use indices starting from 0.
Example:
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
PHP will interpret as
array(4) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
[100]=>
int(-100)
[-100]=>
int(100)
}
Reference- http://php.net/manual/en/language.types.array.php
You can store anything you want in an array.
Will the number/integer be treated as string in such type of array in PHP?
Not upon storing it. However, when you use a value as such, PHP will convert it. The usage of a value determines its interpretation. (Attention, the key is converted upon storing, however, if it is considered numerical)
Not going to put oil on the fire of the PHP Arrays are no arrays here…
But yes, you can put different variable types (string, int, …) together in a PHP thing called Array.