This is probably a simple question but I'm struggling a bit.
$filename = $_GET['type'];
$data = file_get_contents($filename.json);
When I go to my site www.site.com/report.php?type=1
I get the error:
file_get_contents(1json): failed to open
Why is it ignoring the full stop to give me a wrong filename (should be 1.json)
This is how you concat the string:
$data = file_get_contents($filename.".json");
$filename.json is evaluated by PHP as follows:
$filename is a variable, and evaluates to its contents ("1")
. is the concatenation operator
json is a bareword string, which evaluates as if it was quoted ("json"). There is a proposal to remove bareword strings from the language, because they lead to hard-to-track-down errors like this.
When you concatenate "1" and "json", you get 1json.
In order to keep the dot, it must be a string. You can either make use of string interpolation to insert the value of $filename into a string, like this: "$filename.json", or you must explicitly concatenate with a string that contains the dot: $filename . ".json".
PHP will take a dot (.) without quotes as a concatenation sign. but if you will use quotes around the dot like "." it will take this as a string so you should use like following
$filename = $_GET['type'];
$data = file_get_contents($filename.".json");
Related
I'm making the assumption that $_GET variables are interpreted as single quoted strings (and not double quoted strings).
I believe this is true because of the following test (trying to directory traversal attack myself):
$file = "../test.php";
/**
* same as file1 but using hexadecimal encoding, which is a feature
* only available to double quoted strings
* https://www.php.net/manual/en/language.types.string.php
*/
$file2 = "\x2e\x2e\x2ftest.php";
include $file1; // will succeed in my environment
include $file2; // will succeed in my environment
However, if I pass the hexadecimal notation via $_GET, it fails including
the file:
$file3 = $_GET["path"]; // (string) \x2e\x2e\x2ftest.php
include $file3; // will fail in my environment
So my question is: is it really the case that $_GET variables are interpreted as single quoted strings?
(because if so then maybe a simple removing of two consecutive dots from the user input would prevent any directory traversal attack)
And if so, is it written anywhere in the php manual?
Short Answer:
$_GET['path'] is a Variable. PHP will interpret escape sequences only if it found in double quotes, not in a variable. -> Strings Manual.
$get = "\x2e";
var_dump($get);
//string(1) "."
$get = "\\"."x2e";
var_dump($get);
//string(4) "\x2e"
I have the problem, that PHP replaces all spaces with underscores in POST and GET variables.
For example if I have the URL: http://localhost/proxy.php?user name=Max
the browser will convert it to http://localhost/proxy.php?user%20name=Max.
But if I give the $_GET parameters out, the key is not user name but user_name (note the underscore)!
Is there any possibility to change this behaviour?
From the PHP manual:
Dots in incoming variable names
Typically, PHP does not alter the
names of variables when they are
passed into a script. However, it
should be noted that the dot (period,
full stop) is not a valid character in
a PHP variable name. For the reason,
look at it:
<?php $varname.ext; /* invalid variable name */ ?>
Now, what
the parser sees is a variable named
$varname, followed by the string
concatenation operator, followed by
the barestring (i.e. unquoted string
which doesn't match any known key or
reserved words) 'ext'. Obviously, this
doesn't have the intended result.
For this reason, it is important to
note that PHP will automatically
replace any dots in incoming variable
names with underscores.
And a comment on the page:
The full list of field-name characters that PHP converts to _ (underscore) is the following (not just dot):
chr(32) ( ) (space)
chr(46) (.) (dot)
chr(91) ([) (open square bracket)
chr(128) - chr(159) (various)
PHP irreversibly modifies field names containing these characters in an attempt to maintain compatibility with the deprecated register_globals feature.
I think the only possibility to get the wanted parameters, is to parse them on your own using $_SERVER['QUERY_STRING']:
$a_pairs = explode('&', $_SERVER['QUERY_STRING']);
foreach($a_pairs AS $s_pair){
$a_pair = explode('=', $s_pair);
if(count($a_pair) == 1) $a_pair[1] = '';
$a_pair[0] = urldecode($a_pair[0]);
$a_pair[1] = urldecode($a_pair[1]);
$GLOBALS['_GET'][$a_pair[0]] = $a_pair[1];
$_GET[$a_pair[0]] = $a_pair[1];
}
In the old crazy times of register_globals query string was unpacked by PHP into global variables, but the format of variable identifiers is constrained, so obviously spaces couldn't work. This limitation remained, and honestly I believe it's a good idea to keep it this way.
If you really cannot change spaces into underscores in your URLs, just mangle the $_GET array when you process the request and substitute every underscore by a space.
As far as i can remember, i've never seen spaces in URL parameter names...
I think, it would be better to convert all spaces of parameter names into "_".
I am currently using this command:
system('"C:/xampp/htdocs/csv/txtfiles/PSPPfile.txt"');
I want to having something like with having variable inside, for instance:
$file='txtfiles/PSPPfile.txt';
system('"C:/xampp/htdocs/csv/$file"');
Something like above, kindly help me out. Thanks!
Single quoted strings will display things almost completely "as is." Variables and most escape sequences will not be interpreted.
In other words, youre assigning the argument to system to read $file as is, not as what the variable contains.
Use double quotes to assert that variable gets replaced - or perform string concatenation :
system( 'c:/xampp/htdocs/csv/' . $file );
$file = 'txtfiles/PSPPfile.txt';
system('C:/xampp/htdocs/csv/' . $file);
eval("\$data = $myvar('https://www.example.com/json/id='". $_GET['name'] ."'))';
This got me an error, how to concatenate it properly?
Eval is dangerous, but for your specific question above, the quotes were off at the end, and myvar is supposed to be a function. See below:
eval('$data = myvar("https://www.example.com/json/id='. $_GET['name'] .'");');
If you use double quotes like "$data" then $data will first be evaluated and the result or value will be eval'd instead. This is one of the risks of using eval(). If you use double quotes, then escape the $ signs like so:
eval("\$data = myvar('https://www.example.com/json/id=". $_GET['name'] ."');");
Demo: IDEOne
eval("\$data = $myvar('https://www.example.com/json/id=". $_GET['name']."');");
Pretty new to PHP, trying to figure out proper syntax for concatecating variables and such into strings.
For example:
A $mydir = "../../uploads/images/'".$id."'/thumb";
B $mydir = "../../uploads/images/".$id."/thumb";
C $mydir = '../../uploads/images/'.$id.'/thumb";
D $mydir = "../../uploads/images/$id/thumb";
Which one is correct?
What about when you end a string with a variable, but have to comma out to define the next element?
mkdir('../../uploads/images/' . $newid , 0777);
What about when the variable is in the middle?
mkdir('../../uploads/images/' . $newid . '/thumb', 0777);
Lastly, can anyone recommend a good resource for PHP reference? W3Schools isn't cutting it...
Strings in PHP can use either double or single quotes. There is a difference between the two, in that using double quotes will cause PHP to interpolate any variables in the string. For instance:
$var = 'test';
echo "This is a $var"; // outputs: This is a test
echo 'This is a $var'; // outputs: This is a $var
Because of this, using double quotes around your strings is a bit slower, since the string must be interpolated by PHP before it can be output. There is also nowdoc and heredoc support for strings in PHP, as well.
Aside from that distinction there is no difference and you can use them interchangeably, as in the following example:
echo 'I like ' . "concatenating" . ' strings';
It is probably a good idea, though, to be consistent throughout your code. For more information, please refer to the manual
Go to the PHP Manual: http://php.net/manual/en/language.types.string.php
As for the different types of strings:
If you use the double-quoted strings, you can include variables inside of the string like this:
$name = "world";
print("Hello $name");
Single Quotes will not expand variables.
The period is just the concatenation operator. So if you end by concatenating a variable that's fine. I.e. this is ok:
$name = "world";
$greeting = "Hello ".$name;
You shouldn't use your A or B, if you have double quotes, using D is much nicer to read. That is not to say you can't use it, if you like having a hard time reading your strings, go ahead!
The comma after the string doesn't matter
mkdir('../../uploads/images/' . $newid , 0777); // works
mkdir('../../uploads/images/' . $newid . '/thumb', 0777); // works too
mkdir("../../uploads/images/$newid" , 0777); // works and is nicer to read
mkdir("../../uploads/images/$newid/thumb", 0777); // also nicer to read
If the value you want in the string is not a variable, you either have to create a variable, or you have to use regular string concatenation (instead of interpolation)
B and D are correct. The only difference between single and double quotes in PHP is that the content between double quotes is parsed for PHP. From php.net,
When a string is specified in double quotes or with heredoc,
variables are parsed within it.
A - has a pair of unnecessary single quotes.
B - FINE
C - has an incorrect ending quote. should end in a single quote.
D - FINE
for concatenation B or C will both work, however for relative file paths it's usually best to use the
$_SERVER['DOCUMENT_ROOT']
syntax, and access your files relative to your server's html root folder, meaning your syntax will look something like
$_SERVER['DOCUMENT_ROOT']."/folder/foler/".$id."/thumb";
A won't do it.
B is the best.
C has a syntax mistake. Moreover, for strings you generally use ", but on the other hand, ' is used when formatting html like: 'Google!' so you don't need to escape quotes and the code looks nice.
D works, but not recommended. For example in D `"blah $this -> name blah" won't work. That is the reason.
from your choice list, 'B' is fine, so is 'D'. My favorite reference is the official manual: http://www.php.net/manual/en/