Simple way to read variables on different lines from STDIN? - php

I want to read two integers on two lines like:
4
5
This code works:
fscanf(STDIN,"%d",$num);
fscanf(STDIN,"%d",$v);
But I wonder if there's a shorter way to write this? (For more variables, I don't want to write a statement for each variable) Like:
//The following two lines leaves the second variable to be NULL
fscanf(STDIN,"%d%d",$num,$v);
fscanf(STDIN,"%d\n%d",$num,$v);
Update: I solved this using the method provided in the answer to read an array and list to assign variables from an array.

Consider this example:
<?php
$formatCatalog = '%d,%s,%s,%d';
$inputValues = [];
foreach (explode(',', $formatCatalog) as $formatEntry) {
fscanf(STDIN, trim($formatEntry), $inputValues[]);
}
var_dump($inputValues);
When executing and feeding it with
1
foo
bar
4
you will get this output:
array(4) {
[0] =>
int(1)
[1] =>
string(3) "foo"
[2] =>
string(3) "bar"
[3] =>
int(4)
}
Bottom line: you certainly can use loops or similar for the purpose and this can shorten your code a bit. Most of all it simplifies its maintenance. However if you want to specify a format to read with each iteration, then you do need to specify that format somewhere. That is why shortening the code is limited...
Things are different if you do not want to handle different types of input formats. In that case you can use a generic loop:
<?php
$inputValues = [];
while (!feof(STDIN)) {
fscanf(STDIN, '%d', $inputValues[]);
}
var_dump($inputValues);
Now if you feed this with
1
2
3
on standard input and then detach the input (by pressing CTRL-D for example), then the output you get is:
array(3) {
[0] =>
int(1)
[1] =>
int(2)
[2] =>
int(3)
}
The same code is obviously usable with input redirection, so you can feed a file into the script which makes detaching the standard input obsolete...

If you can in your code, try to implement a array :
fscanf(STDIN, "%d\n", $n);
$num=array();
while($n--){
fscanf(STDIN, "%d\n", $num[]);
}
print_r($num);

Related

parse_ini_file converts values of constants into strings, even when using INI_SCANNER_TYPED

INI_SCANNER_TYPED, used as the 3rd argument to parse_ini_file(), should conserve boolean, null and integer values "when possible", according to the documentation
However, when constants are parsed, the values are converted to strings. The documentation is not clear on whether this is expected to happen. It is certainly undesirable, I can't imagine a single scenario where this would be useful. Other scanning types are to be used when you want string conversion, surely?
For example with the following ini file:
NUMBER = 1
TEXT = "1"
DEFINED_INTEGER_CONSTANT = FOO
DEFINED_BOOLEAN_CONSTANT = BAR
UNDEFINED_CONSTANT = BAZ
I use the following php file and get output in comments
<?php
declare(strict_types=1);
define("FOO", 123);
define("BAR", true);
$ini_file = parse_ini_file(__DIR__ . '/test.ini', false, INI_SCANNER_TYPED);
foreach($ini_file as $key => $value) {
define($key, $value);
}
var_dump(NUMBER); // => int(1)
var_dump(TEXT); // => string(1) "1"
var_dump(DEFINED_INTEGER_CONSTANT); // => string(3) "123"
var_dump(DEFINED_BOOLEAN_CONSTANT); // => "1"
var_dump(UNDEFINED_CONSTANT); // => "BAZ"
I neither expect nor want the string conversion in the 3rd and 4th examples. Can I use parse_ini_file to parse constants without string conversion, or do I need to do this another way? Is this something to do with the "where possible" clause in the documentation? Is keeping the original types not possible here for some reason?
Tested in PHP 7.1.26 and 7.3.7.
There does not seem to currently be a way to get parse_ini_file to behave in the expected way.
I have reported this and it has been verified as a bug - see here.

PHP array to cookie breaks on space

I have an array I would like to set as a cookie. The array has spaces in its elements. It breaks when I try to return it.
(unserialized) Array example is:
Array
(
[0] => U06 Bucks
[1] => U07 Stags
[2] => U09 Highlanders
)
To bake my cookie I have:
<?php
$page = $_REQUEST['page'];
if (isset ($_REQUEST['teams'])){
setcookie("team", serialize($_REQUEST['teams']),time()+31536000);
}
else {
// set the expiration date to past
setcookie("team", "", time()-31536000);
}
header('Location:'.$page);
?>
To unbake it, I have:
unserialize($_COOKIE["team"]);
Returns
Array ( [0] => U06 [1] => U07 [2] => U09 )
var_dump($_COOKIE) gives me:
["team"]=> string(64) "YTozOntpOjA7czozOiJVMDYiO2k6MTtzOjM6IlUwNyI7aToyO3M6MzoiVTA5Ijt9" } array(3) { [0]=> string(3) "U06" [1]=> string(3) "U07" [2]=> string(3) "U09" }
According to my browser, the cookie looks like this:
- Name: Team
- Value: YTozOntpOjA7czozOiJVMDYiO2k6MTtzOjM6IlUwNyI7aToyO3M6MzoiVTA5Ijt9
Works fine without spaces in the array and I have tried json_encode via Storing and retrieving an array in a PHP cookie.
Any tips?
The cookies must be urlencoded - use urlencode().
UPDATE
Well, setcookie() urlencodes the data internally, so the problem is somewhere else!
Cookie data must be urlencode()d or rawurlencode()d. PHP does this by itself (setrawcookie() would not). So the source of the issue is still unknown. Try to base64_encode() the cookie and test again:
The cookie data is sent as a header, which value is a sequence of characters excluding semi-colon, comma and white space. (Refere to http://curl.haxx.se/rfc/cookie_spec.html for the exact definition and specs).
setcookie("team", base64_encode(serialize($_REQUEST['teams'])) ,time()+31536000);
$team = isset($_COOKIE['team'])
? unserialize(base64_decode($_COOKIE['team']))
: array();

In PHP, how can I convert an Array (dictionary) inside String variable to Array structure?

I was looking for in Stack some solution to convert a string variable to an Array. The String variable contents this:
$myvar = 'array("a" => array("b1" => 1, "b2" => "something"), "c" => array("d1" => 1))';
I want to convert as:
$myarray = array(
"a" => array (
"b1" => 1,
"b2" => "something"
),
"c" => array("d1" => 1)
);
I was using json_decode after to convert my huge string to json, I used implode too ...
Using eval, I recieve next error:
Parse error: syntax error, unexpected '<' in tabletocreate.php(51) : eval()'d code on line 1
I used print_r($myvar);
The idea it is I have an model inside a file model.php it is only a dictionary, I read this file inside a string and after to convert again an array, I do it because I need to generate a new database from this data, and I have the model for each catalog I need products, offer, ... obiously each model will be different but with the same structure of array, I wrote in the example
SOLUTION
faintsignal resolved the solution in my case: eval("\$myarray = " . $myvar . ';');
Use eval() http://www.php.net/manual/en/function.eval.php
$myarray = eval($myvar)
But don't do this if you're getting the $myvar from outside your script. Also, there are much better methods to serialize and unserialize data in PHP. For instance see http://www.php.net/manual/en/function.serialize.php
If you're reading a .php file directly you have to deal with <?php and ?>. You can pre-parse the file before passing it to eval(). If your file is as simple as:
<?php (php_declarations_and_stuff ?>
You can just remove <?php and ?>, and the eval() the file.
Another option may be just use include against the file. See http://www.php.net/manual/en/function.include.php. In this case include will eval the file in the global scope. Also see that if your included file uses return, you can just retrieve this value directly (See Example #5 in the include reference):
return.php
<?php return 'Ok'; ?>
myfile.php
$val = include('return.php');
print $val;
Will print "Ok".
eval() will accomplish what you need, but as another poster here advided in his answer, you must use this function with great caution.
$myvar = 'array("a" => array("b1" => 1, "b2" => "something"), "c" => array("d1" => 1))';
eval("\$myarray = " . $myvar . ';');
var_dump($myarray);
outputs
array(2) {
["a"]=>
array(2) {
["b1"]=>
int(1)
["b2"]=>
string(9) "something"
}
["c"]=>
array(1) {
["d1"]=>
int(1)
}
}
Someone commented that eval is deprecated but I cannot find any info to support this. However, its use is discouraged, so you might consider it as a last resort when existing PHP functionality will not accomplish your task.

Cleaner way to echo multi dimension array

echo "{$line['text_1']}";
the above echo works fine ,however when it comes to 2d array, in my sublime, only {$line['text_2']} this part work fine. output error both sublime and browser
echo "$array_2d[{$line['text_1']}][{$line['text_2']}]";
any idea?
update
echo "$array_2d[$line['text_1']][$line['text_2']]";
using xampp, error Parse error: syntax error, unexpected '[', expecting ']' in C:\xampp\htdocs
and I'm just outputting a value from the mysql_fetch_assoc. I can do it in another way by echo '' however I'm trying to make my code easier for future editting and code copy paste
and yes I'm doing things like
echo "The price is $array_2d[$line['text_1']][$line['text_2']]"
with lots of html code in the double quote.
Why are you trying to output the array?
if it is for debugging purposes, you can just use the native php functions print_r() or var_dump()
You should be able to say
echo "item is {$array_2d[$line['text1']][$line['text2']]}";
to get to a subelement.
Of course, this is only really useful when it's not the only thing in the string. If you're only echoing the one value, you don't need the quotes, and things get simpler.
echo $array_2d[$line['text1']][$line['text2']];
this should work :
echo $array_2d[$line['text_1']][$line['text_2']];
When echoing variables, you don't have to use the quotes:
echo $array_2d[$line['text_1']][$line['text_2']];
If you do need to output something with that string, the concatentation operator can help you:
echo "Array: " . echo $array_2d[$line['text_1']][$line['text_2']];
You can use print_r() to echo the array.
e.g.:
print_r($array);
Output will be:
Array ( [test] => 1 [test2] => 2 [multi] => Array ( [multi] => 1 [multi2] => 2 ) )
Also you can use this to make it more readable in a HTML context:
echo '<pre>';
print_r($array);
echo '</pre>';
Output will be:
Array
(
[test] => 1
[test2] => 2
[multi] => Array
(
[multi] => 1
[multi2] => 2
)
)
You can use print_r() or var_dump() to echo an array.
The print_r() displays information about a variable in a way that's readable by humans whereas the var_dump() function displays structured information about variables/expressions including its type and value.
$array = 'YOUR ARRAY';
echo "<pre>";
print_r($array);
echo "</pre>";
or
$array = 'YOUR ARRAY';
var_dump($array);
Example variations
I'm wondering why you would try using the $line array as a key to access data in $array_2d.
Anyway, try this:
echo($line['text_1'].'<br>');
this:
echo($array_2d['text_1']['text_2'].'<br>');
and finally this (based on your "the $line array provides the keys for the $array_2d" array example)
$key_a = $line['text_1'];
$key_b = $line['text_2'];
echo($array_2d[$key_a][$key_b].'<br>');
Which can also be written shorter like this:
echo($array_2d[$line['text_1']][$line['text_2']].'<br>');
Verifying/Dumping the array contents
To verify if your arrays hold the data you expect, do not use print_r. Do use var_dump instead as it will return more information you can use to check on any issues you think you might be having.
Example:
echo('<pre>');
var_dump($array_2d);
echo('</pre>');
Differences between var_dump and print_r
The var_dump function displays structured information of a variable (or expression), including its type and value. Arrays are explored recursively with values indented to show structure. var_dump also shows which array values and object properties are references.
print_r on the other hand displays information about a variable in a readable way and array values will be presented in a format that shows keys and elements. But you'll miss out on the details var_dump provides.
Example:
$array = array('test', 1, array('two', 'more'));
output of print_r:
Array
(
[0] => test
[1] => 1
[2] => Array
(
[0] => two
[1] => more
)
)
output of var_dump:
array(3) {
[0]=> string(4) "test"
[1]=> int(1)
[2]=> array(2)
{
[0]=> string(3) "two"
[1]=> string(4) "more"
}
}

Why a loop over MySQL query change an array which has nothing to do with the query?

I have the following piece of code:
print_r($queries);
$id2query = array();
while ($res_array = mysql_fetch_array($results)) {
$id = $res_array['id'];
$query = $res_array['query'];
$id2query[$id] = $query;
}
print_r($queries);
The interesting thing is that printr_r before and after the loop return different things.
Does anybody know how it can be possible?
ADDED
$queries is an array. It shown code is a part of a function and $queries is one of the arguments of the function. Before the loop it returns:
Array ( [0] => )
and after the loop it returns:
Array ( [0] => web 2.0 )
ADDED 2
web 2.0 comes from $res_array. Here is the content of the $res_array:
Array ( [0] => 17 [id] => 17 [1] => web 2.0 [query] => web 2.0 [2]
But I do not understand how a value from $res_array migrates to $queries.
ADDED 3
I tried
print "AAAA".var_dump($queries)."BBB";
it returns AAABBB.
ADDED 4
I have managed to use var_dump in the correct way and this is what it returns before the loop:
array(1) { [0]=> &string(0) "" }
This is what I have after the loop:
array(1) { [0]=> &string(7) "web 2.0" }
But I do not understand what it means.
The var_dump below ADDED 4 shows it, the array contains a reference to a string. So it is not a copy of that string, it is something like a pointer (I know, they are not real pointers, see PHPDocs below) to the original string. So if that one gets changed, the references shows the changed value too.
I'd suggest you have a look at:
PHPDoc References
PHPDoc What references do
Example code:
$s = "lulu";
$a = array(&$s);
var_dump($a);
$s = "lala";
var_dump($a);
First var_dump will return:
array(1) {
[0]=>
&string(4) "lulu"
}
And the second:
array(1) {
[0]=>
&string(4) "lala"
}

Categories