Changes in PHP 5/Zend Engine 2.0 (轉)
Changes in 5/ Engine 2.0
New Model.
PHP's handling of objects has been completely rewritten, allowing for better performance and more features. In previous versions of PHP, objects were handled like primitive types (for instance integers and strings). The drawback of this method was that semantically the whole object was copied when a variable was assigned, or pass as a parameter to a method. In the new approach, objects are referenced by handle, and not by value (one can think of a handle as an object's ntifier).
Many PHP programmers aren't even aware of the copying quirks of the old object model and, therefore, the majority of PHP applications will work out of the box, or with very few modifications.
Private and Protected Members
PHP 5 introduces private and protected member variables, they allow do define the visibility of class properties.
Example
Protected member variables can be accessed in classes extending the class they are declared in, whereas private member variables can only be accessed by the class they belong to.
class
MyClass
{
private $Hello
=
"Hello, World!n"
;
protected $Bar
=
"Hello, Foo!n"
;
protected $Foo
=
"Hello, Bar!n"
;
function
printHello
() {
print
"MyClass::printHello() "
.
$this
->
Hello
;
print
"MyClass::printHello() "
.
$this
->
Bar
;
print
"MyClass::printHello() "
.
$this
->
Foo
;
}
}
class
MyClass2
extends
MyClass
{
protected $Foo
;
function
printHello
() {
MyClass
::
printHello
();
/* Should print */
print
"MyClass2::printHello() "
.
$this
->
Hello
;
/* Shouldn't print out anything */
print
"MyClass2::printHello() "
.
$this
->
Bar
;
/* Shouldn't print (not declared)*/
print
"MyClass2::printHello() "
.
$this
->
Foo
;
/* Should print */
}
}
$obj
= new
MyClass
();
print
$obj
->
Hello
;
/* Shouldn't print out anything */
print
$obj
->
Bar
;
/* Shouldn't print out anything */
print
$obj
->
Foo
;
/* Shouldn't print out anything */
$obj
->
printHello
();
/* Should print */
$obj
= new
MyClass2
();
print
$obj
->
Hello
;
/* Shouldn't print out anything */
print
$obj
->
Bar
;
/* Shouldn't print out anything */
print
$obj
->
Foo
;
/* Shouldn't print out anything */
$obj
->
printHello
();
?>
?php>
Private and protected methods
With PHP 5 (Zend Engine 2), private and protected methods are also introduced.
Example
class
Foo
{
private
function
aPrivateMethod
() {
echo
"Foo::aPrivateMethod() called.n"
;
}
protected
function
aProtectedMethod
() {
echo
"Foo::aProtectedMethod() called.n"
;
$this
->
aPrivateMethod
();
}
}
class
Bar
extends
Foo
{
public
function
aPublicMethod
() {
echo
"Bar::aPublicMethod() called.n"
;
$this
->
aProtectedMethod
();
}
}
$o
= new
Bar
;
$o
->
aPublicMethod
();
?>
?php>
Old code that has no user-defined classes or functions named "public," "protected" or "private" should run without modifications.
Abstract Classes and Methods
PHP 5 also introduces abstract classes and methods. An abstract method only declares the method's signature and does not provide an implementation. A class that contains abstract methods needs to be declared abstract.
Example
abstract
class
AbstractClass
{
abstract public
function
test
();
}
class
ImplementedClass
extends
AbstractClass
{
public
function
test
() {
echo
"ImplementedClass::test() called.n"
;
}
}
$o
= new
ImplementedClass
;
$o
->
test
();
?>
?php>
Abstract classes cannot be instantiated. Old code that has no user-defined classes or functions named 'abstract' should run without modifications.
Interfaces
The Zend Engine 2.0 introduces interfaces. A class may implement an arbitrary list of interfaces.
Example
interface Throwable
{
public
function
getMessage
();
}
class
Exception implements Throwable
{
public
function
getMessage
() {
// ...
}
?>
?php>
Old code that has no user-defined classes or functions named 'interface' or 'implements' should run without modifications.
Class Type Hints
While remaining loosely typed PHP 5 introduces the ability to use class type hints to declare the expected class of objects that are passed as parameters to a method.
Example
interface Foo
{
function
a
(
Foo $foo
);
}
interface Bar
{
function
b
(
Bar $bar
);
}
class
FooBar implements Foo
,
Bar
{
function
a
(
Foo $foo
) {
// ...
}
function
b
(
Bar $bar
) {
// ...
}
}
$a
= new
FooBar
;
$b
= new
FooBar
;
$a
->
a
(
$b
);
$a
->
b
(
$b
);
?>
?php>
These class type hints are not checked upon compilation, as would be the case in a typed language, but during runtime. This means that:
function
foo
(
ClassName $object
) {
// ...
}
?>
?php>
is equivalent to:
function
foo
(
$object
) {
if (!(
$object instanceof ClassName
)) {
die(
"Argument 1 must be an instance of ClassName"
);
}
}
?>
?php>
This syntax only applies to objects/classes, not built-in types.
final
PHP 5 introduces the "final" key to declare final members and methods. Methods and members declared final cannot be overridden by sub-classes.
Example
class
Foo
{
final
function
bar
() {
// ...
}
}
?>
?php>
Old code that has no user-defined classes or functions named 'final' should run without modifications.
Object Cloning
PHP 4 (Zend Engine 1.0) offered no way a user could decide what copy constructor to run when an object is duplicated. During duplication, PHP 4 did a bit for bit copy making an identical replica of all the object's properties.
Creating a copy of an object with fully replicated properties is not always the wanted behavior. A good example of the need for copy constructors, is if you have an object which represents a GTK window and the object holds the re of this GTK window, when you create a duplicate you might want to create a new window with the same properties and have the new object hold the resource of the new window. Another example is if your object holds a reference to another object which it uses and when you replicate the parent object you want to create a new instance of this other object so that the replica has its own separate copy.
An object copy is created by calling the object's __clone()
method:
$copy_of_object
=
$object
->
__clone
();
?>
?php>
When the developer asks to create a new copy of an object, the Zend Engine will check if a __clone()
method has been defined or not. If not, it will call a default __clone()
which will copy all of the object's properties. If a __clone()
method is defined, then it will be responsible to set the necessary properties in the created object. For convenience, the engine will supply a function that imports all of the properties from the source object, so that they can start with a by-value replica of the source object, and only override properties that need to be changed.
Example
class
MyCloneable
{
static
$id
=
0
;
function
MyCloneable
() {
$this
->
id
=
self
::
$id
++;
}
function
__clone
() {
$this
->
name
=
$that
->
name
;
$this
->
address
=
"New York"
;
$this
->
id
=
self
::
$id
++;
}
}
$obj
= new
MyCloneable
();
$obj
->
name
=
"Hello"
;
$obj
->
address
=
"Tel-Aviv"
;
print
$obj
->
id
.
"n"
;
$obj
=
$obj
->
__clone
();
print
$obj
->
id
.
"n"
;
print
$obj
->
name
.
"n"
;
print
$obj
->
address
.
"n"
;
?>
?php>
Unified Constructors
The Zend Engine allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
With PHP 4, constructor methods were class methods that had the same name as the class itself. Since it is very common to call parent constructors from derived classes, the way PHP 4 worked made it a bit cumbersome to move classes around in a large class hierarchy. If a class is moved to reside under a different parent, the constructor name of that parent changes as well, and the code in the derived class that calls the parent constructor has to be modified.
PHP 5 introduces a standard way of declaring constructor methods by calling them by the name __construct()
.
Example
class
BaseClass
{
function
__construct
() {
print
"In BaseClass constructorn"
;
}
}
class
SubClass
extends
BaseClass
{
function
__construct
() {
parent
::
__construct
();
print
"In SubClass constructorn"
;
}
}
$obj
= new
BaseClass
();
$obj
= new
SubClass
();
?>
?php>
For backwards compatibility, if PHP 5 cannot find a __construct()
function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct()
which was used for different semantics.
Destructors
Having the ability to define destructors for objects can be very useful. Destructors can log messages for deging, close database connections and do other clean-up work. No mechanism for object destructors existed in PHP 4, although PHP had already support for registering functions which should be run on request shutdown.
PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as : When the last reference to an object is destroyed the object's destructor, which is a class method name %__destruct()% that recieves no parameters, is called before the object is freed from memory.
Example
class
MyDestructableClass
{
function
__construct
() {
print
"In constructorn"
;
$this
->
name
=
"MyDestructableClass"
;
}
function
__destruct
() {
print
"Destroying "
.
$this
->
name
.
"n"
;
}
}
$obj
= new
MyDestructableClass
();
?>
?php>
Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct()
in the destructor body.
Constants
PHP 5 introduces per-class constants:
class
Foo
{
const
constant
=
"constant"
;
}
echo
"Foo::constant = "
.
Foo
::
constant
.
"n"
;
?>
?php>
PHP 5 allows for expressions within constants, however, constants are evaluated at compile time, therefore no constants can be declared that rely on runtime information.
class
Bar
{
const
a
=
1
<<
0
;
const
b
=
1
<<
1
;
const
c
=
a
|
b
;
}
?>
?php>
Old code that has no user-defined classes or functions named 'const' will run without modifications.
Exceptions
PHP 4 had no exception handling. PHP 5 introduces a exception model similar to that of other programming languages.
Example
class
MyExceptionFoo
extends
Exception
{
function
__construct
(
$exception
) {
parent
::
__construct
(
$exception
);
}
}
try
{
throw
new
MyExceptionFoo
(
"Hello"
);
}
catch
(
MyException $exception
) {
print
$exception
->
getMessage
();
}
?>
?php>
Old code that has no user-defined classes or functions 'catch', 'throw' and 'try' will run without modifications.
Dereferencing objects returned from functions
In PHP 4 it wasn't possible to dereference objects returned by functions and make further method calls on those objects. With the advent of Zend Engine 2, the following is now possible:
class
Circle
{
function
draw
() {
print
"Circlen"
;
}
}
class
Square
{
function
draw
() {
print
"Squaren"
;
}
}
function
ShapeFactoryMethod
(
$shape
) {
switch (
$shape
) {
case
"Circle"
:
return new
Circle
();
case
"Square"
:
return new
Square
();
}
}
ShapeFactoryMethod
(
"Circle"
)->
draw
();
ShapeFactoryMethod
(
"Square"
)->
draw
();
?>
?php>
Static member variables of static classes can now be initialized
Example
class
foo
{
static
$my_static
=
5
;
}
print
foo
::
$my_static
;
?>
?php>
Static Methods
PHP 5 introduces the 'static' keyword to declare a method static, thus callable from outside the object context.
Example
class
Foo
{
public
static function
aStaticMethod
() {
// ...
}
}
Foo
::
aStaticMethod
();
?>
?php>
The pseudo variable $this is not available inside a method that has been declared static.
instanceof
PHP 5 introduces the instanceof
keyword, that allows you to ascertain whether or not an object is an instance of a class, or extends a class, or implements an interface.
Example
class
baseClass
{ }
$a
= new
baseClass
;
if (
$a instanceof basicClass
) {
echo
"Hello World"
;
}
?>
?php>
Static function variables
Statics are now treated at compile-time which allows developers to assign variables to statics by reference. This change also greatly improves their performance but means that indirect references to statics will not work anymore.
Parameters that are passed by reference to a function may now have default values
Example
function
my_function
(&
$var
=
null
) {
if (
$var
===
null
) {
die(
"$var needs to have a value"
);
}
}
?>
?php>
__autoload()
The __autoload()
interceptor function will be automatically called when an undeclared class is to be instantiated. The name of that class will be passed to the __autoload() interceptor function as its only argument.
Example
function
__autoload
(
$className
) {
include_once
$className
.
".php"
;
}
$object
= new
ClassName
;
?>
?php>
Overloadable Method calls and Property accesses
Both method calls and property accesses can be overloaded via the __call()
, __get()
and __set()
methods.
Example: __get() and __set()
class
Setter
{
public $n
;
public $x
= array(
"a"
=>
1
,
"b"
=>
2
,
"c"
=>
3
);
function
__get
(
$nm
) {
print
"Getting
[
$nm
]n
"
;
if (isset(
$this
->
x
[
$nm
])) {
$r
=
$this
->
x
[
$nm
];
print
"Returning: $r
n
"
;
return
$r
;
} else {
print
"Nothing!n"
;
}
}
function
__set
(
$nm
,
$val
) {
print
"Setting
[
$nm
]
to $val
n
"
;
if (isset(
$this
->
x
[
$nm
])) {
$this
->
x
[
$nm
] =
$val
;
print
"OK!n"
;
} else {
print
"Not OK!n"
;
}
}
}
$foo
= new
Setter
();
$foo
->
n
=
1
;
$foo
->
a
=
100
;
$foo
->
a
++;
$foo
->
z
++;
var_dump
(
$foo
);
?>
?php>
Example: __call()
class
Caller
{
var
$x
= array(
1
,
2
,
3
);
function
__call
(
$m
,
$a
) {
print
"Method $m called:
n
"
;
var_dump
(
$a
);
return
$this
->
x
;
}
}
$foo
= new
Caller
();
$a
=
$foo
->
test
(
1
,
"2"
,
3.4
,
true
);
var_dump
(
$a
);
?>
?php>
:namespace prefix = o ns = "urn:schemas--com::office" />
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-997972/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PHP 危矣?Zend Engine 團隊宣佈脫離 Rogue WavePHP
- PHP5.3安裝Zend Guard Loader圖文教程PHP
- Zend Studio使用教程:使用PHP 7進行開發(二)PHP
- Apache2.4+php5.3無法載入Zend問題ApachePHP
- php-src原始碼zend_startup_builtin_functions函式PHP原始碼UIFunction函式
- 初識分散式圖資料庫 Nebula Graph 2.0 Query Engine分散式資料庫
- 【PHP7原始碼分析】PHP7原始碼研究之淺談Zend虛擬機器PHP原始碼虛擬機
- zend_objects_store_putObject
- zend_std_read_property
- zend_lookup_class_ex
- 基於多Engine、Navigator2.0實現混合棧管理方案實踐
- ZEND_RETURN_SPEC_CONST_HANDLER
- Zend OPcache 最佳實踐配置opcache
- [Reactive] Run functions when data changesReactFunction
- zend_vm_stack_push_call_frame
- php 微信機器人 Vbot 2.0PHP機器人
- Magento新的ZEND FRAMEWORK安全漏洞Framework
- PHP 7.4 新特性 —— 箭頭函式 2.0PHP函式
- gin.engine
- pytorch 轉 tensorRT 踩的幾個小坑_tensorrt engine set up failedPyTorchAI
- ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLEROBJ
- "Visual Studio Code is unable to watch for file changes in this large workspace"
- PHP轉Go系列:字串PHPGo字串
- PHP stdClass Object轉arrayPHPObject
- PHP 5 與 PHP 7 的效能對比PHP
- fio: engine libaio not loadableAI
- AIRVPS WEB APP ENGINEAIWebAPP
- 安裝 Docker EngineDocker
- VBScript Scripting Engine初探
- flask資料庫遷移 No changes in schema detected.Flask資料庫
- [LeetCode] 3226. Number of Bit Changes to Make Two Integers EqualLeetCode
- music-PHP 2.0 - 一個 PHP 寫的命令列音樂搜尋下載器PHP命令列
- PHP xml 轉陣列 陣列轉 xml 操作PHPXML陣列
- 探究Flutter Engine除錯Flutter除錯
- Flutter Engine環境搭建Flutter
- 5、php責任鏈模式PHP模式
- 5. PHP 函式 strstr ()PHP函式
- PHP 5 Dockerfile 改造過程PHPDocker
- php /golang 5年求職PHPGolang求職