php 面向对象

给自己看的

简介

PHP 对待对象的方式与引用 (references) 和句柄 (handles) 相同,即每个变量都持有对象的引用,而不是整个对象的拷贝。

用户空间命名指南

全局命名空间

以下代码结构会进入全局命名空间:

  • functions(函数)
  • classes(类)
  • interfaces(接口)
  • constants(常量,并非类常量)
  • 在函数/方法之外定义的变量

规则

以下列表指出了 PHP 工程在选择新的内部标识符时保留给自己的权利。最终指南是官方的» 编码标准

  • PHP 拥有最顶层命名空间,但是会尝试找到合体的描述命名以避免任何明显的冲突。
  • 函数名在两个词中间使用下划线,类名则同时使用 camelCasePascalCase 规则。
  • PHP 在任何扩展库的全局符号前附加上扩展库的名称(此规则在过去则有无数例外)。例如:
  • Iterators 和 Exceptions 则只是简单加上 "Iterator" 和 "Exception" 后缀。例如:

提示

防止命名冲突方法:

  1. 在命名后加上下划线,和三四个不常用的字符。(不再推荐)
  2. 命名空间。
  3. 减少全局作用域的变量的数量。

变量范围

  1. include 就是把代码物理的塞进来。
  2. 全局范围变量 global 和 $GLOBALS 。$GLOBALS 是一个超全局数组。
  3. static 。static $int = 1+2; // Static declarations are resolved in compile-time.

变量

变量定义:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

基础

<?php
class SimpleClass{
    public $var;
}
$instance = new SimpleClass();

$assigned   =  $instance;
$reference  =& $instance;

$instance->var = '$assigned will have this value';

unset($instance); // $instance and $reference become null

var_dump($instance);
var_dump($reference);
var_dump($assigned);

/**********
Notice: Undefined variable: instance in C:\Users\haobi\Desktop\a.php on line 14
NULL
object(SimpleClass)#1 (1) {
  ["var"]=>
  string(30) "$assigned will have this value"
}
object(SimpleClass)#1 (1) {
  ["var"]=>
  string(30) "$assigned will have this value"
}
**********/
<?php
class SimpleClass{
    public $var;
}
$instance = new SimpleClass();

$assigned   =  $instance;
$reference  =& $instance;

$instance->var = '$assigned will have this value';

$instance = null; // $instance and $reference become null

var_dump($instance);
var_dump($reference);
var_dump($assigned);

/**********
NULL
NULL
object(SimpleClass)#1 (1) {
  ["var"]=>
  string(30) "$assigned will have this value"
}
**********/
<?php
class Test
{
    static public function getNew()
    {
        return new static;
    }
}

class Child extends Test
{}

$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);

$obj3 = Test::getNew();
var_dump($obj3 instanceof Test);

$obj4 = Child::getNew();
var_dump($obj4 instanceof Child);
var_dump($obj4 instanceof Test);
var_dump($obj3 == $obj4);
var_dump($obj3 === $obj4);

/**********
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
bool(false)
**********/

ClassName::class 编译时候解析,并不会加载该类,如果不存在,并不会发生错误。

$this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object).

属性

<?php
$ref = new StdClass();
$ref->{'ref-type'} = 'Journal Article';
var_dump($ref);

// 但是不能 $ref->ref-type ,神奇。
<?php
class Foo {
    // As of PHP 7.1.0 开始支持设置可见性
    public const AA = 'bar';
    private const BB = 'baz';
    protected const CC = 'baz';
}
echo Foo::AA, PHP_EOL;
echo Foo::BB, PHP_EOL;    // wrong
echo Foo::CC, PHP_EOL;    // wrong

自动加载 classes

Autoloading is not available if using PHP in CLI interactive mode.

<?php
spl_autoload_register(function ($name) {
    echo "Want to load $name.\n";
    throw new MissingException("Unable to load $name.");
});

try {
    $obj = new NonLoadableClass();
} catch (Exception $e) {
    echo $e->getMessage(), "\n";
}

/**
Want to load NonLoadableClass.
Want to load MissingException.

Fatal error: Class 'MissingException' not found in testMissingException.php on line 4
*/

构造与解析函数

The destructor will be called even if script execution is stopped using exit(). Calling exit() in a destructor will prevent the remaining shutdown routines from executing.

Note:

Destructors called during the script shutdown have HTTP headers already sent. The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).

Note:

Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error.

可见性

<?php
class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }

    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}

class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}

$myFoo = new Foo();
$myFoo->test(); 

/**
Bar::testPrivate 
Foo::testPublic
*/ 

同一个类的不同对象可以相互访问它们的私有属性和保护属性。

接口

接口也可以继承,通过使用 extends 操作符。

请注意,可以在接口中声明构造函数,在某些情况下可能有用,例如 供工厂使用。

在接口中声明的所有方法都必须是公共的; 这是一个接口的本质。

接口常量的工作方式与类常量完全相同,除非它们不能被继承它们的类/接口覆盖。

Traits

<?php
trait PropertiesTrait {
    public $same = true;
    public $different = false;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = true; // Allowed as of PHP 7.0.0; E_STRICT notice formerly
    public $different = true; // Fatal error
}
# Example using parent class:
<?php
class TestClass {
    public static $_bar;
}
class Foo1 extends TestClass { }
class Foo2 extends TestClass { }
Foo1::$_bar = 'Hello';
Foo2::$_bar = 'World';
echo Foo1::$_bar . ' ' . Foo2::$_bar; // Prints: World World
?>

# Example using trait:
<?php
trait TestTrait {
    public static $_bar;
}
class Foo1 {
    use TestTrait;
}
class Foo2 {
    use TestTrait;
}
Foo1::$_bar = 'Hello';
Foo2::$_bar = 'World';
echo Foo1::$_bar . ' ' . Foo2::$_bar; // Prints: Hello World

匿名类

<?php
function anonymous_class()
{
    return new class {};
}

if (get_class(anonymous_class()) === get_class(anonymous_class())) {
    echo 'same class';
} else {
    echo 'different class';
}


// same class

魔术方法

<?php

class A
{
    public $var1;
    public $var2;

    public static function __set_state($an_array) // As of PHP 5.1.0
    {
        $obj = new A;
        $obj->var1 = $an_array['var1'];
        $obj->var2 = $an_array['var2'];
        return $obj;
    }
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';

eval('$b = ' . var_export($a, true) . ';'); 

var_dump($b);

/**
object(A)#2 (2) {
  ["var1"]=>
  int(5)
  ["var2"]=>
  string(3) "foo"
}
*/
<?php
class C {
    private $prop;

    public function __construct($val) {
        $this->prop = $val;
    }

    public function __debugInfo() {
        return [
            'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));
?>

/**
object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}
*/

This method is called by var_dump() when dumping an object to get the properties that should be shown. If the method isn't defined on an object, then all public, protected and private properties will be shown.

This feature was added in PHP 5.6.0.

后期静态绑定

static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。

<?php
class A {
    public static function foo() {
        static::who();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__."\n";
    }
}

C::test();

/**
A
C
C
*/

对象和引用

<?php
class A {
    public $foo = 1;
}  

$e = new A;

function foo($obj) {
    // ($obj) = ($e) = <id>
    $obj->foo = 4;
}

foo($e);
echo $e->foo."\n";


// 输出 4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352