Skip to content

Instantly share code, notes, and snippets.

@alcaeus
Created September 19, 2019 15:05
Show Gist options
  • Save alcaeus/711dd2f63e36c72013de7002e0d08be5 to your computer and use it in GitHub Desktop.
Save alcaeus/711dd2f63e36c72013de7002e0d08be5 to your computer and use it in GitHub Desktop.
declare_vars examples
<?php
/*
* When enabled, forces all variables to be declared before read/write access.
* The feature can be turned on and off.
*/
declare(declare_vars=1);
var_dump($undeclaredVar); // Compile error
$undeclaredVar = 'something'; // Compile error
isset($undeclaredVar); // Compile error
var $declaredVar; // Variable declared and can be used
var $initializedVar = 'Initial Value'; // Variable declared with initial value
var $object = new stdClass(); // Any value allowed as initial value
var_dump($declaredVar); // null
var_dump($initializedVar); // "Initial Value"
var_dump($object); // Object(stdClass)
declare(declare_vars=0);
var_dump($anotherUndeclaredVar); // No compile error
?>
<?php
/*
* TBD: When disabled, the "var" keyword causes a compile error
*/
var $declaredVar; // Compile error: declare_vars is disabled
?>
<?php
/*
* Redeclaring variables is not allowed. This is necessary because variables may
* be typed later.
*/
declare(declare_vars=1);
var $declaredVar;
var $declaredVar; // Compile error: variable already declared
?>
<?php
/*
* Variables that are implicitly declared with declare_vars=0 count as declared
* if declare_vars is turned on later in the file.
*/
$implicitlyDeclaredVar = 'Initial value'; // No compile error
var_dump($undeclaredVar); // No compile error
declare(declare_vars=1);
var_dump($implicitlyDeclaredVar); // No error
var_dump($undeclaredVar); // Compile error
?>
<?php
// includedFile.php
var_dump($declaredVar); // null
var_dump($undeclaredVar); // Warning: undefined variable
$implicitlyDeclaredVar = 'Initial Value'; // Variable is implicitly declared
/*
* When including files, declare_vars is not inherited. Scope, however, is.
*/
declare(declare_vars=1);
var $declaredVar;
include('includedFile.php');
var_dump($implicitlyDeclaredVar); // "Initial Value"
var_dump($undeclaredVar); // Compile error
?>
<?php
/*
* Variable variable access is evaluated at runtime. With declare_vars=1,
* accessing an undeclared variable will throw an Error exception that can be
* caught and handled.
*/
declare(declare_vars=1);
var $variableName = 'otherVariable';
var $otherVariable = 'foo';
var_dump($$variableName); // "foo"
var_dump($$otherVariable); // Error exception
?>
<?php
/*
* It is possible to declare dynamic variables. However, they may not be
* redeclared as per the example above.
*/
declare(declare_vars=1);
var $variableName = 'otherVariable';
var $$variableName = 'foo';
var_dump($otherVariable); // "foo"
?>
<?php
/*
* Variables remain declared when leaving a scope, even if the variable was
* declared within that scope. A scope inherits all variables from the parent
* scope.
*/
declare(declare_vars=1);
var $topScopedVar = 'foo';
{
var $scopedVar = 'bar';
var_dump($topScopedVar); // "foo"
var_dump($scopedVar); // "bar"
}
var_dump($topScopedVar); // "foo"
var_dump($scopedVar); // "bar"
?>
<?php
/*
* Classes declared within a declared_vars=1 scope require all properties to be
* declared. This also counts if the code accessing a class instance is running
* with declare_vars=0
*/
declare(declare_vars=1);
class DoesNotAllowUndeclaredProperties
{
public $declaredProperty;
public function __construct()
{
var $propertyName = 'undeclaredProperty';
$this->undeclaredProperty = 'Initial value'; // Compile error
$this->$propertyName = 'Initial Value'; // Error exception
}
}
var $object = new DoesNotAllowUndeclaredProperties();
var $propertyName = 'undeclaredProperty';
var_dump($object->undeclaredProperty); // Compile error
var_dump($object->$propertyName); // Error exception
declare(declare_vars=0);
var_dump($object->undeclaredProperty); // Still a compile error
?>
<?php
/*
* PHP's built-in classes are declared with declare_vars=0. This is especially
* important for stdClass, which is used when returning objects from json_decode.
*/
declare(declare_vars=1);
$object = new stdClass();
$object->foo = 'bar'; // No error
?>
<?php
/*
* TBD: Magic __get, __set, __isset, and __unset are not allowed when using
* declare_vars=1
*/
declare(declare_vars=1);
// Compile error: using magic method "__get" is not allowed when using
// declare_vars=1
class AllowsUndeclaredPropertiesViaMagicMethods
{
public function __get()
{
return 'foo';
}
public function __set()
{
// noop
}
}
?>
<?php
declare(declare_vars=1);
/*
* In the future, we may decide to implement lexical scope for variables. This
* would undeclare all variables that were declared in the current scope once
* leaving this scope
*/
declare(declare_vars=1);
var $topScopedVar = 'foo';
{
var $scopedVar = 'bar';
var_dump($topScopedVar); // "foo"
var_dump($scopedVar); // "bar"
}
var_dump($topScopedVar); // "foo"
var_dump($scopedVar); // Compile error
?>
<?php
/*
* Typed variables will require variable declarations
*/
declare(declare_vars=1);
var string $declaredString = 'Foo';
var int $declaredInt = 0;
var ?Class $object;
var_dump($object); // Uninitialized
$object = null;
var_dump($object); // null
$object = new stdClass(); // Type error
$object = new Class();
var_dump($object); // Object(Class)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment