why do php variables need to be identified by $? [duplicate] - php

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does PHP have a $ sign in front of variables?
In languages like bash and Perl, strings need not be quoted and that is why variable access needs to be identified by using $. Why does PHP need the similar mechanism?

It's a historical decision, probably because it allows to include variables in a string literal:
$variable = "handle to data storage";
echo "a $variable";

Because PHP is influenced by Perl. Back then, when it was conceived, PHP was just a set of Perl scripts.

PHP Constants are a seperate type, but behave much like variables (except they can't be changed, of course... that's what they're constants for) and look a lot like 'em too. For readability, it's nicer to have an identifier. (<- random guess, not)
Besides:
$lol = abcdef;
$lol === 'abcdef'; // true
Undefined constants will throw a notice and will be interpreted as a string.
ohyes, and inside strings, variables can also be used, so an identifier is absolutely necessary (thanks to phihag)

I think simply because without it mixing variable inside string will not be possible
$name = "bond";
echo "My name is $name" ;
Now without $ name will act as string .

Related

Using arrays keys without quotes, how to fix it on big project? [duplicate]

This question already has answers here:
How to fix associative array keys that lack single quotation marks in multiple files
(4 answers)
Closed 7 months ago.
I started a project using much arrays keys without quotes.
And now I having problems with this method, i didn't knew it was bad when i started my project. I finally wanted to display E_NOTICES errors for reasons but it crash because the log is overloaded with millions notices like PHP Notice: Use of undefined constant message - assumed 'key'.
So to fix it I could add quotes to my keys in my whole project but there are so much ! Is there a way to achieve this with an algorithme or anything to fix my code ? I want replace any undefined constant by a string with quotes, EG:
$my_array[key] by $my_array['key'].
Thanks.
EDIT:
I succeeded to fix all declarations using rejex, like this:
\[([^0-9\$\'\"\]])([^\'\"\]]*)\] to \[\'\1\2\'\]
But it is not enough, there are much situations where unquoted keys are used without brackets, EG:
array_key_exists(unquotedKey,$array)
$array['key'] = array( unquotedKey => array(96,56) );
etc...
I could fix all situations using regex but I guess I will have much troubles to handle it well, and sometimes keys of my arrays are really constants and it shouldn't be quoted ! If anybody have a better solution it would help me a lot.
The perfect solution would be to be able to get my code after PHP replaced undefined constants by quoted strings, is it possible ? It does it each time I compile, it is maybe stored somewhere temporarily.
I use Notepad++ which has a search and replace in files feature (Ctrl + Shift + F). With regular expression mode on, you could use
Search:
\$my_array\[([^\'\"]+)\]
Replace
\$my_array\[\'$1\'\]
The search looks for anything within the array key square brackets where there is not already a " or ' character, which would indicate the declaration is already valid.
Select the directory of your project then hit "Replace in Files". Ensure your entire project is backed up first in case something goes wrong.
Use this pattern
[a-zA-Z0-9]{1,}(\[([^'"$0-9]+)\])
to find array keys without quotes like this:
$_POST[content_id]

Defining constants with $GLOBALS

I want to use a global variable setup where they are all declared, initialized and use friendly syntax in PHP so I came up with this idea:
<?
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
$GLOBALS['debugger'] = 1; // set $GLOBALS['debugger'] to 1
DEFINE('DEBUGGER','$GLOBALS["debugger"]'); // friendly access to it globally
echo "1:" . DEBUGGER . ":<br>";
echo "2:" . ${DEBUGGER}. ":<br>";
echo "3:" . $GLOBALS['debugger'] . ":<br>";
if (DEBUGGER==1) {echo "DEBUG SET";}
?>
generates the following:
1:$GLOBALS["debugger"]:
Notice: Undefined variable: $GLOBALS["debugger"] in /home/tra50118/public_html/php/test.php on line 8
2::
3:1:
How can there be an error with 2: when clearly $GLOBALS["debugger"] IS defined? And then not generate a similar notice with the test at line 10?
I think what I am trying to do is to force PHP to interpret a string ($GLOBALS["debugger"]) as a variable at run time i.e. a constant variable variable
Disclaimer: I agree with the comments, globals are generally a bad idea.
That said, there's a few questions here that are worth answering, and the concept of indirection is useful, so here goes.
${'$GLOBALS["debugger"]'} is undefined. You don't include the leading '$' when using indirection. So, the correct version would be define('DEBUGGER', 'GLOBALS["debugger"]').
But, this doesn't work either. You can only access one level down via indirection. So you can access the array $GLOBALS, but you can't access keys in that array. Hence, you might use :
define('DEBUGGER', 'debugger');
${DEBUGGER};
This isn't useful, practically. You may as well just use $debugger directly, as it's been defined as a global and will be available everywhere. You may need to define global $debugger; at the start of functions however.
The reason your if statement is not causing notices is because you defined DEBUGGER to be a string. Since you aren't trying to use indirection in that line at all, it ends up reading as:
if ("$GLOBALS['debugger']"==1) {echo "DEBUG SET";}
This is clearly never true, though it is entirely valid PHP code.
I think you may have your constants crossed a bit.
DEFINE('DEBUGGER','$GLOBALS["debugger"]'); sets the constant DEBUGGER to the string $GLOBALS["debugger"].
Note that this is neither the value nor the reference, just a string.
Which causes these results:
1: Output the string $GLOBALS["debugger"]
2: Output the value of the variable named $GLOBALS["debugger"]. Note that this is the variable named "$GLOBALS["debugger"]", not the value of the key "debugger" in the array $GLOBALS. Thus a warning occurs, since that variable is undefined.
3: Output the actual value of $GLOBALS["debugger"]
Hopefully that all makes sense.
OK, thanks to all who answered. I think I get it now, I am new to PHP having come form a C++ background and was treating the define like the C++ #define and assuming it just did a string replace in the precompile/run phase.
In precis, I just wanted to use something like
DEBUGGER = 1;
instead of
$GLOBALS['debugger'] = 1;
for a whole lot of legitimate reasons; not the least of which is preventing simple typos stuffing you up. Alas, it appears this is not doable in PHP.
Thanks for the help, appreciated.
You can not use "variable variables" with any of the superglobal arrays, of which $GLOBALS is one, if you intend to do so inside an array or method. To get the behavior you would have to use $$, but this will not work as I mentioned.
Constants in php are already global, so I don't know what this would buy you from your example, or what you are going for.
Your last comparison "works" because you are setting the constant to a string, and it is possible with PHP's typecasting to compare a string to an integer. Of course it evaluates to false, which might be surprising to you, since you expected it to actually work.

would it make a difference if I omit single quotes in $_variable['variable']? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Accessing arrays whitout quoting the key
I noticed there's a subtle difference... if I were to code this:
echo "Welcome, $_SESSION['username'], you are logged in.";
It will fail at parsing. However if I code like this:
echo "Welcome, $_SESSION[username], you are logged in.";
It works as expected which makes me wonder if single quotes are really necessary? I cannot find anything in PHP documentation showing that effect.
In PHP, a global constant that isn't defined becomes a string.
Don't rely on this; always quote your array keys.
However, interpolated into a string, it is fine, as it is already a string.
Konforce makes a good point in the comments about using braces in string interpolation.
If you omit them, don't quote the key.
If you use them, you must quote the key, otherwise the constant will be looked up.
This way is wrong but works$_SESSION[username] and take more time to parse the value of that associative index.
That effect PHP performance
Always use quotes around a string
literal array index. For example,
$foo['bar'] is correct, while
$foo[bar] is not. This is wrong, but
it works. The reason is that this code
has an undefined constant (bar) rather
than a string ('bar' - notice the
quotes).PHP may in future define constants which, unfortunately for such code, have the same name. It works because PHP automatically converts a bare string (an unquoted string which does not correspond to any known symbol) into a string which contains the bare string. For instance, if there is no defined constant named bar, then PHP will substitute in the string 'bar' and use that.
you should use quotes while accessing values.
Please check this document
in section Array do's and don'ts
<?php
// Show all errors
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Correct
print $arr['fruit']; // apple
print $arr['veggie']; // carrot
// Incorrect. This works but also throws a PHP error of level E_NOTICE because
// of an undefined constant named fruit
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit]; // apple
// This defines a constant to demonstrate what's going on. The value 'veggie'
// is assigned to a constant named fruit.
define('fruit', 'veggie');
// Notice the difference now
print $arr['fruit']; // apple
print $arr[fruit]; // carrot
// The following is okay, as it's inside a string. Constants are not looked for
// within strings, so no E_NOTICE occurs here
print "Hello $arr[fruit]"; // Hello apple
// With one exception: braces surrounding arrays within strings allows constants
// to be interpreted
print "Hello {$arr[fruit]}"; // Hello carrot
print "Hello {$arr['fruit']}"; // Hello apple
// This will not work, and will result in a parse error, such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using superglobals in strings as well
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";
// Concatenation is another option
print "Hello " . $arr['fruit']; // Hello apple
?>
Inside a string you have to omit the single quotes or wrap the whole variable in {} ("...{$array['key']}..." or ...$array[key]...). However, wrapping it is highly recommended to prevent issues when having something like "...$foobar..." where you actually wanted "...{$foo}bar..." (i.e. the var $foo followed by bar).
But you might not want to use in-string vars at all but properly end the string: '...' . $var . '...'
It's called bare strings as mentioned, strangly enough, in the array documentation. If no constant is found matching the bare string - It's, for historical reasons, assumbed to be a string literal. This syntax is however ridden with a lot of syntactic problems that I won't go into, also readability is a problem here. The reader questions himself - Is this a constant or a string?
Modern PHP versions emit a warning for this syntax, as to help fix this problem by using singly quoted strings ('username').
yes.
If you pass an argument for an array without any quotes, php will first try to interpret the argument as a constant and if it isn't defined, it will act as expected.Even though it can give the same result, it is significantly slower that the quoted argument.
Here's an example of when this might not work :
define("a_constant","a value");
$a = array("a_constant"=>"the right value");
echo $a[a_constant];
The a_constant variable has the value "a value", so $a[a_constant] gets translated to $a["a value"], a key which does not exist in the array $a.

PHP variable variables in {} symbols

I get the basics of variable variables, but I saw a syntax just know, which bogles my mind a bit.
$this->{$toShow}();
I don't really see what those {} symbols are doing there. Do they have any special meaning?
PHP's variable parser isn't greedy. The {} are used to indicate what should be considered part of a variable reference and what isn't. Consider this:
$arr = array();
$arr[3] = array();
$arr[3][4] = 'Hi there';
echo "$arr[3][4]";
Notice the double quotes. You'd expect this to output Hi there, but you actually end up seeing Array[4]. This is due to the non-greediness of the parser. It will check for only ONE level of array indexing while interpolating variables into the string, so what it really saw was this:
echo $arr[3], "[4]";
But, doing
echo "{$arr[3][4]}";
forces PHP to treat everything inside the braces as a variable reference, and you end up with the expected Hi there.
They tell the parser, where a variable name starts and ends. In this particular case it might not be needed, but consider this example:
$this->$toShow[0]
What should the parser do? Is $toShow an array or $this->$toShow ? In this case, the variable is resolved first and the array index is applied to the resulting property.
So if you actually want to access $toShow[0], you have to write:
$this->{$toShow[0]}
These curly braces can be used to use expressions to specify the variable identifier instead of just a variable’s value:
$var = 'foo';
echo ${$var.'bar'}; // echoes the value of $foobar
echo $$var.'bar'; // echoes the value of $foo concatenated with "bar"
$this->{$toShow}();
Break it down as below:
First this is a object oriented programming style as you got to see $this and ->. Second, {$toShow}() is a method(function) as you can see the () brackets.
So now {$toShow}() should somehow be parsed to a name like 'compute()'. And, $toShow is just a variable which might hold a possible function name. But the question remains, why is {} used around.
The reason is {} brackets substitues the value in the place. To clarify,
$toShow="compute";
so,
{$toShow}(); //is equivalent to compute();
but this is not true:
$toShow(); //this is wrong as a variablename is not a legal function name

Concatenation Operator

This might be a silly question but it struck me, and here i ask.
<?php
$x="Hi";
$y=" There";
$z = $x.$y;
$a = "$x$y";
echo "$z"."<br />"."$a";
?>
$z uses the traditional concatenation operator provided by php and concatenates, conversely $a doesn't,
My questions:
by not using the concatenation operator, does it effect the performance?
If it doesn't why at all have the concatenation operator.
Why have 2 modes of implementation when one does the work?
Only slightly, since PHP has to parse the entire string looking for variables, while with concatenation, it just slaps the two variables together. So there's a tiny performance hit, but it's not noticeable for most things.
It's a lot easier to concatenate variables like $_SERVER['DOCUMENT_ROOT'] using the concatenation operator (with quotes, you have to surround the variable in brackets or remove the single quotes in the array index; plus it just makes the string look all ugly). Plus, the concatenation operator allows more flexibility for formatting. For example, you can break up a long string literal onto multiple lines and then concatenate the different parts of it:
$blah = "This is a really really long string. I don't even know how " .
"long it is, but it's really long. Like, longer than an eel " .
"or even a boa constrictor. Wow.";
You can also use the concatenation operator to directly include return values from functions in a string literal (you can't include a function call in a double-quoted string), like this:
$blah = "This has a " . fn_call() . " result, which can't go in the quotes.";
I'm not sure I entirely understand what you're asking here, but I can say that PHP borrows a lot of things from Perl, and one of Perl's mantras is "There's more than one way to do it."
a. Yes. PHP has to parse the string for variables.
b. Because of lines like: echo 'Your Ip address is' . get_ip() . '.';
For reasons A and B.
In some cases your write less with:
$someLongVarName ="Hi";
$someLongVarName .=" there";
VS
$someLongVarName ="Hi";
$someLongVarName = "$someLongVarName there";
Addressing your last question:
Every language has multiple was of doing the same thing. Flexibility is important in every language since any given method may be better the another from situation to situation. The only thing that you should worry about in regards to this is to be consistent in your own code.

Categories