Strange PHP array behaviour [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP String in Array Only Returns First Character
I've got following problem. When I run script below I got string(1) "F" as an output. How is that possible? No error, notice displayed.. nothing. Key whatever doesn't exist in $c. Can you explain that?
<?php
$c = 'FEEDBACK_REGISTER_ACTIVATION_COMPLETED_MSG';
var_dump ($c['whatever']);
?>
I'm having this issue on PHP 5.3.3. (LINUX)

PHP lets you index on strings:
$str = "Hello, world!";
echo $str[0]; // H
echo $str[3]; // l
PHP also converts strings to integers implicitly, but when it fails, uses zero:
$str = "1";
echo $str + 1; // 2
$str = "invalid";
echo $str + 1; // 1
So what it's trying to do is index on the string, but the index is not an integer, so it tries to convert the string to an integer, yielding zero, and then it's accessing the first character of the string, which happens to be F.

Through Magic type casting of PHP when an associative array can not find the index, index itself is converted to int 0 and hence it is like
if
$sample = 'Sample';
$sample['anystring'] = $sample[0];
so if o/p is 'S';

Related

Need Explaination about Plus/Minus/Multiply and Devide in PHP [duplicate]

This question already has answers here:
PHP is confused when adding and concatenating
(3 answers)
Closed 6 years ago.
Today i am working on a small PHP code to plus/minus and multiply, but i end up found something which i wasn't knew before.
I was Plus 2 value, 123456+123456=24690 and my code is this:
<?php
$value1=12345;
$value2=12345;
$output=$value1+$value2;
echo $output;
?>
Which return a correct value:
So than i have to print this value with string Like this:
Total Value: 24690
I use this code:
echo 'Total Value:'.$value1+$value2;
Its return: 12345 instead of
Total Value: 24690
I know that "." isn't a Arithmetic operators, so i need small explanation why is this doing that.
But when i do
echo 'Total Value:'.($value1+$value2);
Its work fine!
Little Confused!
It first concatenates the $value1 with the string and then tries to add it to a string and number can't be added to string and hence you get that output.
While using braces, it just concatenates the contents of the brace and performs the mathematical operation inside the brace.
It follows BODMAS
When you
echo 'Total Value:'.$value1+$value2;
code execution will be like this actually:
echo ('Total Value: ' . $value1) + $value2;
This behavior is called Type Juggling. From the manual it states:
a variable's type is determined by the context in which the variable is used. That is to say, if a string value is assigned to variable $var, $var becomes a string. If an integer value is then assigned to $var, it becomes an integer.
Example:
$foo = "1"; // $foo is string (ASCII 49)
$foo *= 2; // $foo is now an integer (2)
More examples on the link.

php variables, strings and arrays: associative array returns first letter of string

I understand that, with a sting assigned to a variable, individual characters can be expressed by using the variable as an indexed array, but why does the code below, using an associative array, not just die with missing required? Why does 'isset' not throw FALSE on an array key that definitely doesn't exist?
unset($a);
$a = 'TESTSTRING';
if(!isset($a['anystring'])){
die('MISSING REQUIRED');
}else{
var_dump($a['anystring']);
}
The above example will output:
string(1) "T"
EDIT:
As indicated by Jelle Keiser, this is probably the safer thing to do:
if(!array_key_exists('required',$_POST)){
die('MISSING REQUIRED');
}else{
echo $_POST['required'];
}
What PHP is doing is using your string as a numeric index. In this case, 'anystring' is the equivalent of 0. You can test this by doing
<?php
echo (int)'anystring';
// 0
var_dump('anystring' == 0);
// bool(true)
PHP does a lot of type juggling, which can lead to "interesting" results.
$a is a string not an associative array.
If you want to access it that way you have to do something like this.
$a['anystring'] = 'TESTSTRING';
You need to use array_key_exists() to test if a key exists
The working of isset is correct in your case.
Because $a is a string, the index-operator will give you the specified char in the string at the declared position. (like a "Char-Array")
A small example:
$a = 'TESTSTRING';
echo $a[0]; // Output: T
echo $a[1]; // Output: E
// ...
This will output the first and the second character at index 0 and 1 of the string.
And because the index-operator always expects an integer value on strings. The given value will be automatically casted to an integer. You can see this, when you cast the string to an integer, like this:
echo (int) 'TESTSTRING'; // Output: 0
For char-access on strings, also see the PHP-Manual.
Try enabling PHP to show all errors by using error_reporting(E_ALL);
This should give you a warning saying you are using an illegal offset. PHP therefore automatically assumes you are looking for the first element in the array or letter in this case.
it works as expected for... it returned false... but when I force it to return true ... itz throws an error saying illegal offset somekind.... but still output the first string.... as anystring casted as int equals to 0.. check the version of php you are using bro... I used notepad++ to create the php file... no special ide...

PHP : is it dynamich thing or any thing else

Anyone can explain it why is it true
$a = Array('b' = > 'okokokok');
if ( isset( $a['b']['ok'] ) ) {
echo $a['b']['ok']; // Print 0
} else {
echo "else";
}
This was for backward compatibility with PHP 4 (see PHP Bug #29883). When casting a string to an integer, and the string is not a valid integer, it becomes 0 (zero). The letter "o" is printed because that is the character at offset 0 in the string.
In PHP 5.4, the behavior intentionally changed (see PHP Bug #60362); that PHP version instead prints "else".
First of all, it doesn't print '0', but lowercase 'o'.
Try this:
$string = 'abc';
echo $string['omgwhysuchkeyworks'];
It will print 'a'. That is because it seems in PHP when you try any key (other than numeric) on string variable it will return the first character of the string. That's also why isset($a['b']['ok']) returns true.
And it might be an issue of the PHP version. Perhaps on newer version it will work as intended (it will write 'else')
It prints else. 'ok' is no array index but a value on index 'b' of array $a:
Array
(
[b] => okokokok
)
See http://ideone.com/50EhGW
$a = Array('b' = > 'okokokok');
if ( isset( $a['b']['ok'] ) ) {
echo $a['b']['ok']; // Print 0
} else {
echo "else";
}
When you have a string ,you can treat it as array. its indexes would be numerical, starting from zero to string length minus one. But if you try to pass a string as index (ok in this case) , PHP tries to convert it to integer , evaluates it as zero(intval('ok')). On systems with php 5.4, it treat differently and checks the key itself and doesn't do the converting .So, in one system it may print else and on the other it prints o.

strlen on array returns 5 in php

From the docs -
int strlen ( string $string )
it takes string as a parameter, now when I am doing this-
$a = array('tex','ben');
echo strlen($a);
Output -
5
However I was expecting, two type of output-
If it is an array, php might convert it into string so the array will become-
'texben' so it may output - 6
If 1st one is not it will convert it something like this -
"array('tex','ben')" so the expected output should be - 18 (count of all items)
But every time it output- 5
My consideration from the output is 5 from array word count but I am not sure. If it is the case how PHP is doing this ?(means counting 5)
The function casts the input as a string, and so arrays become Array, which is why you get a count of 5.
It's the same as doing:
$a = array('tex','ben');
echo (string)$a; // Array
var_dump((string)$a); // string(5) "Array"
This is the behavior prior to PHP 5.3. However in PHP 5.3 and above, strlen() will return NULL for arrays.
From the Manual:
strlen() returns NULL when executed on arrays, and an E_WARNING level error is emitted.
Prior [to 5.3.0] versions treated arrays as the string Array, thus returning a string length of 5 and emitting an E_NOTICE level error.
Use
$a = array('tex','ben');
$lengths = array_map('strlen',$a);
to get an array of individual lengths, or
$a = array('tex','ben');
$totalLength = array_sum(array_map('strlen',$a));
to get the total of all lengths
The array is implicitly converted to a string. In PHP this yields the output Array, which has 5 letters as strlen() told you.
You can easily verify this, by running this code:
$a = array('tex','ben');
echo $a;

PHP and access to string like to assoc array

Is that logical behavior?
$str = 'string';
$res = $str['some_key'];
echo (int)isset($str['some_key']); // 1
echo $res; // 's'
It's a bug or unclear feature?
It is a "feature". When using $string[$index], $index is treated as integer, so 'some_key' is converted to 0. That's also why you get 's' (first letter of $str) in $res.
$str = 'Lorem';
var_dump($str['key']); // L, because (int)'key' is 0
var_dump($str['0key']); // L
var_dump($str['1key']); // o, because (int)'1key' is 1
var_dump($str['2key']); // r
var_dump($str['3key']); // e, because (int)'3key' is 3
var_dump($str['4key']); // m
var_dump($str['5key']); // Notice: Uninitialized string offset: 5 in sandbox\index.php on line 20
Accessing strings like arrays is a feature.
Strings only have numeric offsets, any "key" you use is cast to an int.
Non-numeric strings cast to the int 0.
Hence $str["foo"] is equivalent to $str[0].
So there is a logic, whether you want to call it logical or not is up to you.
But if you're accessing strings with string keys, something's wrong with your code anyway. ;-)

Categories