PHP integer-like strings - php

when i am using string to access array index, editor show warning.
As of PHP 5.4 string offsets have to either be integers or
integer-like strings, otherwise a warning will be thrown.
can any body please explain the "integer-like strings" ? or reason for showing warning.
Additionally if same is use for $_POST it didn't show any warning.
Below snippet gives warning.
$POST = $_POST;
$POST['username']
While below didn't
$_POST['username']

I would call integer-like strings everything php can convert to an integer, basically everything.
Which editor are you using? This warning is nonsense, php has the ability to use integers or strings as array index, thus you basically can dump everthing into the index of the array (Probably not an object).
$ar = array();
$ar['a string'] = 'Content';
$ar['11string'] = 'More Content';
$ar['1'] = 'More content';
$ar[1] = 'Even more';
All of these things are allowed.
EDIT:
As ShiraNai7 pointed out, the error is about accessing strings via the array modifier, in this case you are only allowed to use integers (or as said integer-like strings). This is primary the case, because you are accessing the n-th character of an string.
Still, there is no reason to show this warning at this point. Maybe you have some more complex code at this point, override $POST to a string?

Related

Why does treating integers as arrays ($int[$index]) not raise any errors in PHP? [duplicate]

This question already has an answer here:
How does the "Array dereferencing" work on a scalar value of type boolean/integer/float/string as of PHP version 7.2.0?
(1 answer)
Closed 5 years ago.
This is just a simple question out of curiosity. I spent the whole day debugging my PHP code, and found the problem was due to treating an integer as an array:
$x = $int[$index]; // this returns null, but no error at all
The integer was actually meant to be an array, but the function that was meant to pass the array messed up and passed the first value in the array instead. Is there any reason why an error isn't shown? Accessing an undefined index on an array creates an error, however trying to access a non-existent index on an integer doesn't?
I originally thought; it typecasts $int to a string because [] is another way of accessing string positions. Seems plausible that that wouldn't generate an error:
$string 'Hello';
echo $string[0]; // H
However, that's not the case:
$int = 1;
echo $int[0];
Outputs nothing and var_dump($int[0]) returns NULL.
Interestingly, the same behavior is exhibited for bool and float and the operation used is FETCH_DIM_R which is Fetch the value of the element at "index" in "array-value" to store it in "result".
From the manual Arrays:
Note: Array dereferencing a scalar value which is not a string silently yields NULL, i.e. without issuing an error message.
Similar to this phenomenon, where no error is generated. Bugs #68110 and #54556:
$array['a'] = null;
echo $array['a']['non-existent'];
Not surprising that assigning doesn't work:
$int = 1;
$int[0] = 2;
Warning: Cannot use a scalar value as an array
So PHP is actually attempting to access the int, bool, float as an array but not generating an error. This is from at least version 4.3.0 to 7.2.2.
Contrary to my original theory that you're invoking undefined behavior, this behavior actually is defined in the Array documentation.
Note:
Array dereferencing a scalar value which is not a string silently yields NULL, i.e. without issuing an error message.
In that case, it seems like there's no type juggling happening at all, so these references to documentation regarding conversion to array aren't useful in understanding this.
Explicit conversion to array is defined.
For any of the types integer, float, string, boolean and resource, converting a value to an array results in an array with a single element with index zero and the value of the scalar which was converted. In other words, (array)$scalarValue is exactly the same as array($scalarValue).
Automatic conversion to array is undefined according to the type juggling documenation.
Note:
The behaviour of an automatic conversion to array is currently undefined.
At first I thought this was what was happening in this case, but since salathe pointed out that this behavior is documented elsewhere, I'm not sure what "automatic conversion to array" is.
As to why this gives you a null value without throwing an error, warning, or notice, that's just how the PHP interpreter was implemented, and as far as why that is the case, it's not really answerable here. You'd have to ask the developers, and they might be able to tell you.
this is "type juggling", a "feature" of PHP.
you can read more in the official doc
EDIT
According to documentation, "The behaviour of an automatic conversion to array is currently undefined."
I run a quick test, just for curiosity:
<?php
$int = 1;
$index = 0;
$x = $int[$index];
echo gettype($int[$index]) . PHP_EOL;
var_dump($x);
and the output shows that gettype() returns NULL, so I guess that, in this case, is converted to NULL

php variable in an array

$q2=$_REQUEST['binge'];
'book2'=>array('callno'=>123006,'price'=>number_format(844,2),'desc'=>'Binge','auth'=>'Tyler Oakley','quant'=>$q2,'total'=>number_format(844,2)*$q2)
On this particular code, It kept displaying errors like this
Warning: A non-numeric value encountered in C:\xampp\htdocs\Webcard_3new\Webcard\wishlist.php on line 97
I searched all over the net for finding the right answers but some are just so complex to understand...
It supposed to be that $q2 is the variable inside an array. That variable is then multiplied to the "TOTAL". but the errors kept on going.. please help!!
The super-globals will always be strings. You need to explicitly convert them using intval():
$q2 = intval($_REQUEST['binge']);
Also, this line:
'book2'=>array...
Should be
$book2 = array...
You can use
$q2 = filter_var($_REQUEST['binge'], FILTER_VALIDATE_INT);
here you will have the benefit of validation where false is returned when someone passes a value that is not an integer. If it is instead a float use FILTER_VALIDATE_FLOAT instead.
Also, consider using $_GET, or $_POST directly to have more control of the data channel. $_REQUEST cobbles together several things into one, which sometimes may cause issues when more than one channel have the same key.

Php array offset passes 'isset', even though it's not set

The easiest way for me to explain this is to show an example ... Here's a replication of the problem code:
<?php
$test=array();
$test['one']='hello';
if(isset($test['one']['two'][0])) {
echo 'Apparently it is set ...';
echo $test['one']['two'][0];
}
?>
This returns as:
Apparently it is set ...
Warning: Illegal string offset 'two' in C:\test.php on line 6
h
Is this because there are mixed key types? It's just a little anomaly I came across and was wondering if someone could shed some light on it ...
The reason is that, when you dereference a string, it will return a string comprising a single character (assuming the index doesn't exceed the length); the resulting string can be dereferenced again (starting from 5.4 onwards).
For example - link:
$s = 'hello';
$s[0]; // "h"
$s[0][0]; // "h"
// etc. etc.
Illegal indices such as 'two' will cause a notice but it's treated as index 0, except when used inside isset().
Another example:
$s[0][1]; // ""
$s[0][1][0]; // notice: uninitialised string offset: 0
If you don't know beforehand whether a string or array is passed and this is important to you, additional type checks need to take place in between each path.
You should check your all your array keys exist before you try and use them, i.e. all the way up the chain. isset() accepts multiple parameters so you don't need to keep rewriting it and can keep DRY principles going a little more:
$test = array();
$test['one'] = 'hello';
if (isset($test['one'], $test['one']['two'], $test['one']['two'][0])) {
echo 'Apparently it is set ...';
echo $test['one']['two'][0];
}
isset returns odd and unexpected results when you pass it a string instead of an array.
It is good practice to pair an an is_array check with an isset check.

How do I parse this string: a:10:{1:0;s:7:"default";i:1; ...?

How can I read strings like that? What do they mean?
a:10:{i:0;s:7:"default";i:1;s:8:"failsafe";i:2;s:4:"foaf";i:3;s:4:"ical";i:4;s:2:"js";i:5;s:4:"json";i:6;s:6:"opendd";i:7;s:3:"php";i:8;s:3:"rss";i:9;s:3:"xml";}
I've seen a lot of systems which use strings like that, stores it in the database and parse to get the values. How can I parse them?
Thanks.
This is a serialized string. Look at the results of var_dump(unserialize()). It is NOT a valid JSON-formatted string (json_decode() will return null).
If you want to actually "read" it without unserializing it, you can see "a:10" means array with 10 indices. "i:0" means "index zero" and is semicolon-separated with the corresponding value ("s:7" is a string of length 7). The values are comma separated. Classes can also be serialized.
It's not JSON, it is a serialized array. Use unserialize() to turn it into something usable.

how do i use php to read an external file and put insides into variables?

I had no idea to correctly form the title of this question, because I don't even know if what I'm trying to do has a name.
Let's say I've got an external file (called, for instance, settings.txt) with the following in it:
template:'xaddict';
editor:'true';
wysiwyg:'false';
These are simple name:value pairs.
I would like to have php take care of this file in such a way that I end up with php variables with the following values:
$template = 'xaddict';
$editor = 'true';
$wysiwyg = 'false';
I don't know how many of these variables I'll have.
How should i go and do this?
The data inside the file is in simple name:value pairs. No nesting, no complex data. All the names need to be converted to $name and all the values need to be converted to 'value', disregarding whether it is truly a string or not.
$settings = json_decode(file_get_contents($filename));
assuming your file is in valid JSON format. If not, you can either massage it so it is or you'll have to use a different approach.
Do you want 'true' in "editor:'true'" to be interpreted as a string or as a boolean? If sometimes string, sometimes boolean, how do you know which?
If you have "number='9'" do you want '9' interpreted as a string or an as an integer? Would '09' be a decimal number or octal? How about "number='3.14'": string or float? If sometimes one, sometimes the other, how do you know which?
If you have "'" (single quote) inside a value is it escaped? If so, how?
Is there any expectation of array data?
Etc.
Edit: This would be the simplest way, imo, to use your example input to retrieve your example data:
$file = 'test.csv';
$fp = fopen($file, 'r');
while ($line = fgetcsv($fp, 1024, ':')) {
$$line[0] = $line[1];
}
If you use JSON, you can use something like:
extract(json_decode(file_get_contents('settings.json')));
Using extract may be dangerous, so I suggest to store these settings in an array:
$settings = json_decode(file_get_contents('settings.json'));
You should read your file to an array, with the file() function, then you should cycle on it: for each line (the file() function will return an array, one line per item), check if the line is not blank, then explode() on the ":" character, trim the pieces, and put them into an array.
You will end up win an array like this:
[template] = xaddict
[editor] = true
then you can use this information.
Do not automatically convert this into local variables: it's a great way to introduce security risks, and potentially very obscure bugs (local variables obscured by those introduced by this parsing).

Categories