"Note: $this is a special variable that can't be assigned."
While the PHP runtime generates an error if you directly assign $this in code, it doesn't for $$name when name is 'this'.
<?php
$this = 'text'; // error
$name = 'this';
$$name = 'text'; // sets $this to 'text'
?>
Podstawy
Każdą zmienną w PHP zapisuje się, poprzedzając jej nazwę znakiem dolara "$". Wielkość liter w nazwie zmiennej jest rozróżniana.
Nazw zmiennych dotyczą te same reguły, co innych rodzajów nazw w PHP. Poprawna nazwa zmiennej zaczyna się od litery lub znaku podkreślenia "_", po których może wystąpić dowolna ilość liter, cyfr lub znaków podkreślenia. Jako wyrażenie regularne, można to zapisać tak: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Informacja: W naszym rozumieniu, litery to znaki a-z, A-Z i bajty od 127 do 255 (0x7f-0xff).
Informacja: $this to specialna zmienna, której nie można definiować.
Zobacz także Userland Naming Guide.
Aby uzyskać więcej informacji na temat funkcji powiązanych ze zmiennymi, zobacz Funkcje Obsługi Zmiennych.
<?php
$zmienna = 'Pan';
$Zmienna = 'Jan';
echo "$zmienna, $Zmienna"; // wyświetla "Pan, Jan"
$7dni = 'tydzień'; // niepoprawna nazwa - zaczyna się od cyfry
$_7dni = 'tydzień'; // poprawna nazwa - zaczyna się znakiem podkreślenia
$jaźń = 'osobowość'; // poprawna nazwa - "ń" i "ź" należą do ASCII 127-255
?>
Domyślnie, zmienne zawsze są zawsze przypisywane przez wartość. Innymi słowy, jeśli przypiszesz do zmiennej jakieś wyrażenie, wartość tego wyrażenia zostanie skopiowana do zmiennej. Oznacza to, że po przypisaniu wartości jednej zmiennej do drugiej, późniejsza zmiana wartości jednej z nich nie spowoduje zmiany wartości drugiej. Więcej informacji na ten temat w rozdziale Wyrażenia.
PHP oferuje jeszcze jeden sposób przypisywania wartości do zmiennych: przypisanie przez referencję. Oznacza to, że nowa zmienna tylko odnosi się (innymi słowy, "staje się aliasem" lub "wskazuje na") do pierwotnej zmiennej. Zmiany wykonane na nowej zmiennej oddziałują także na pierwotną zmienną i vice versa.
Aby przypisać przez referencję, postaw znak ampersand (&) przed nazwą zmiennej przypisywanej (zmiennej od której pobierasz wartość). Na przykład poniższy kod wyświetla "To jest PHP" dwa razy:
<?php
$foo = "PHP"; // Przypisz wartość "PHP" do $foo.
$bar = &$foo; // Przypisz referencyjnie $foo do $bar.
$bar = "To jest $bar"; // Zmień $bar...
echo $bar;
echo $foo; // $foo też się zmieniło.
?>
Należy pamiętać, że tylko wyrażenia posiadające nazwę mogą być przypisane przez referencję.
<?php
$foo = 25;
$bar = &$foo; // Przypisanie poprawne.
$bar = &(24 * 7); // Przypisanie niepoprawne - do nienazwanego wyrażenia.
function test()
{
return 25;
}
$bar = &test(); // Niepoprawne.
?>
W PHP nie jest konieczne inicjowanie zmiennych, jednak jest to bardzo
dobry nawyk. Niezainicjowane zmienne mają domyślne wartości dla ich typu, zależnie od kontekstu, w jaki zmienne te zostały użyte
- zmienne logiczne typu boolean domyślnie przyjmują wartość FALSE, zmiennym całkowitym typu integer domyślnie nadawane jest zero, łańcuchom tekstowym
(np. użytym wewnątrz echo()) nadany jest łańcuch pusty, natomiast tablice zostają pustymi tablicami.
Przykład #1 Domyślne wartości niezainicjowanych zmiennych
<?php
// Zmienna bez nadanej wartości ORAZ bez odwołań do niej (brak kontekstu, w jakim została użyta); zwróci NULL
var_dump($zmienna_bez_kontekstu_uzycia);
// Używanie zmiennej logicznej typu boolean; zwróci 'false' (Zobacz informacje o operatorach trójparametrowych, by poznać tę składnię)
echo($nieinicjowana_zmiena_bool ? "true\n" : "false\n");
// Używanie łańcuchów; zwróci 'string(3) "abc"'
$nieinicjowany_lancuch .= 'abc';
var_dump($nieinicjowany_lancuch);
// Używanie zmiennych całkowitych; zwróci 'int(25)'
$nieinicjowana_zmienna_int += 25; // 0 + 25 => 25
var_dump($nieinicjowana_zmienna_int);
// Używanie zmiennych typu float/double; zwróci 'float(1.25)'
$nieinicjowana_zmienna_float += 1.25;
var_dump($nieinicjowana_zmienna_float);
// Używanie tablicy; zwróci array(1) { [3]=> string(3) "def" }
$nieinicjowana_tablica[3] = "def"; // array() + array(3 => "def") => array(3 => "def")
var_dump($nieinicjowana_tablica);
// Używanie obiektu; stworzy nowy obiekt stdClass (zobacz http://www.php.net/manual/pl/reserved.classes.php)
// Zwróci: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
$nieinicjowany_obiekt->foo = 'bar';
var_dump($nieinicjowany_obiekt);
?>
Poleganie na domyślnej wartości niezainicjowanej zmiennej jest problematyczne, w razie zawarcia jednego pliku wewnątrz innego, posiadającego tak samo nazwane zmienne. Jest to również poważne zagrożenie dla bezpieczeństwa przy włączonej opcji register_globals. Ostrzeżenie klasy E_NOTICE pojawi się podczas pracy z niezainicjowanymi zmiennymi, jednak w przypadku przypisywania elentów do niezainicjowanych tablic - już nie. Funkcja isset() może zostać użyta w celu wykrycia, czy zmienna została już zainicjowana.
If you need to check user entered value for a proper PHP variable naming convention you need to add ^ to the above regular expression so that the regular expression should be '^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'.
Example
<?php
$name="20011aa";
if(!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/',$name))
echo $name.' is not a valid PHP variable name';
else
echo $name.' is valid PHP variable name';
?>
Outputs: 2011aa is valid PHP variable name
but
<?php
$name="20011aa";
if(!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/',$name))
echo $name.' is not a valid PHP variable name';
else
echo $name.' is valid PHP variable name';
?>
Outputs: 2011aa is not a valid PHP variable name
This page should include a note on variable lifecycle:
Before a variable is used, it has no existence. It is unset. It is possible to check if a variable doesn't exist by using isset(). This returns true provided the variable exists and isn't set to null. With the exception of null, the value a variable holds plays no part in determining whether a variable is set.
Setting an existing variable to null is a way of unsetting a variable. Another way is variables may be destroyed by using the unset() construct.
<?php
print isset($a); // $a is not set. Prints false. (Or more accurately prints ''.)
$b = 0; // isset($b) returns true (or more accurately '1')
$c = array(); // isset($c) returns true
$b = null; // Now isset($b) returns false;
unset($c); // Now isset($c) returns false;
?>
is_null() is an equivalent test to checking that isset() is false.
The first time that a variable is used in a scope, it's automatically created. After this isset is true. At the point at which it is created it also receives a type according to the context.
<?php
$a_bool = true; // a boolean
$a_str = 'foo'; // a string
?>
If it is used without having been given a value then it is uninitalized and it receives the default value for the type. The default values are the _empty_ values. E.g Booleans default to FALSE, integers and floats default to zero, strings to the empty string '', arrays to the empty array.
A variable can be tested for emptiness using empty();
<?php
$a = 0; //This isset, but is empty
?>
Unset variables are also empty.
<?php
empty($vessel); // returns true. Also $vessel is unset.
?>
Everything above applies to array elements too.
<?php
$item = array();
//Now isset($item) returns true. But isset($item['unicorn']) is false.
//empty($item) is true, and so is empty($item['unicorn']
$item['unicorn'] = '';
//Now isset($item['unicorn']) is true. And empty($item) is false.
//But empty($item['unicorn']) is still true;
$item['unicorn'] = 'Pink unicorn';
//isset($item['unicorn']) is still true. And empty($item) is still false.
//But now empty($item['unicorn']) is false;
?>
For arrays, this is important because accessing a non-existent array item can trigger errors; you may want to test arrays and array items for existence with isset before using them.
When wanting to switch two variables from content, you can use the XOR operator:
<?PHP
$a=5;
$b=3;
//Please mind the order of these, as it's important for the outcome.
$a^=$b;
$b^=$a;
$a^=$b;
echo $a.PHP_EOL.$b;
/* prints:
3
5
*/
?>
This will also work on strings, but it won't work on arrays and objects, so for them you'll have to use the serialize() function before the operation, and the unserialize() function after.
