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.
Related
Why below code is printing the "here", it should be "there"
$a = "171E-10314";
if($a == '0')
{
echo "here";
}
else
{
echo "there";
}
PHP automatically parses anything that's a number or an integer inside a string to an integer. "171E-10314" is another way of telling PHP to calculate 171 * 10 ^ -10314, which equates to (almost) 0. So when you do $a == '0', the '0' will equate to 0 according to PHP, and it returns true.
If you want to compare strings, use the strcmp function or use the strict comparator ===.
when you use the == comparison, PHP tries to cast to different data types to check for a match like that
in your case:
'0' becomes 0
"171E-10314" is still mathematically almost 0 but I think PHP just rounds it to 0 due to the resolution of float.
check this link for a visual representation:
http://www.wolframalpha.com/input/?i=171E-10314
As per the answers given I tried to convert the string into numerical:
$a = "171E-10314" + 0;
print $a;
And I got output as 0.
Thats why it is printing here.
Use === /*(this is for the 30 character)*/
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...
Why does the following code work:
$test = array(0=>'test1','field0'=>'test2',1=>'test3','field1'=>'test4');
echo array_search('test4',$test);
But the following doesn't:
$test = array(0=>0,'field0'=>'test2',1=>'test3','field1'=>'test4');
echo array_search('test4',$test);
If you had a mixed array from say mysql_fetch_array($result,MYSQL_BOTH) and took the keys which you needed to search you wouldn't be able too - it would never progress further than 0.
Try to do array_search('test4',$test, TRUE);. The 3rd parameter tells it to use === instead of == when comparing.
Since your array holds both strings and numbers, when it compares to the 0 (the 1st element), it converts 'test4' to a number (it stops at the 1st non-numeric character) and it happens to match.
What I mean is: 'test4' == 0 => 0 == 0 => true.
When you pass TRUE as the 3rd parameter, it uses ===, and 'test4' === 0 is automatically false since the types don't match, there is no conversion.
The solution = force the 0 value to be a string:
$test = array(0=>0,'field0'=>'test2',1=>'test3','field1'=>'test4');
foreach ($test as $k=>$v){ $test[$k] = (string) $v; }
echo array_search('test4',$test);
You can't search a number for a string and expect a good result.
My guess is it sees the value as a number, so it converts your string to a number (which it can't) so that string gets converted to a 0. So the value of 0 equals the search string, which also equals 0, and there's your result.
If the value is 1, it won't match as the search string gets converted to a 0 (as you can't convert a string to a number) so it wouldn't match in the following.
$test = array(0=>1,'field0'=>'test2',1=>'test3','field1'=>'test4');
You'll only get your exact case scenario when that value in the array is 0.
I'm having a problem with PHP's isset function. It's often and mysteriously (to me) misfiring.
For instance, when I have a variable that can be either a string or an error array, I try using isset to see if the variable contains one of the known indexes of the array, like so:
$a = "72";
if(isset($a["ErrorTable"]))
echo "YES";
else
echo "NO";
This bad boy prints YES all the way on my server. I tried it on Ideone (online interpreter thingie. It's cool!) here: http://ideone.com/r6QKhK and it prints out NO.
I'm thinking this has something to do with the PHP version we're using. Can someone shed some light into this?
Consider the following piece of code:
$a = "72";
var_dump( isset($a["ErrorTable"]) );
You're checking if $a["ErrorTable"] is set. PHP first typecasts any non-numeric offset to int and this makes ErrorTable equal to 0.
Essentially, you're just doing:
if ( isset($a[0]) )
Strings in PHP can be accessed an array, and $a[0] is definitely set and the condition will evaluate to TRUE.
However, this weird behavior was fixed in PHP 5.4.0 and the changelog for isset() says:
5.4.0 -- Checking non-numeric offsets of strings now returns FALSE.
Your server is probably using an older version of PHP and that would explain why it outputs YES.
You can use array_key_exists() instead:
$a = "72";
if ( is_array($a) && array_key_exists('ErrorTable', $a) ) {
echo 'YES';
} else {
echo 'NO';
}
The output will be NO on all PHP versions.
I usually use the empty function like:
$a = "72";
if(!empty($a["ErrorTable"]))
echo "YES";
else
echo "NO";
$a[0] is a way of referencing the 1st character in the string, which is the value "7". Because string characters are simply referenced by their numeric value, the "ErrorTable" is typecast to an int (0)
This is the case in PHP 5.2.17 and 5.3.23, but not in 5.4.15 or 5.5.0
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. ;-)