亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP保留類及特殊類

2020-03-22 17:52:04
字體:
來源:轉載
供稿:網友

html' target='_blank'>面向對象語言中,都會內置一些語言內置提供的基本功能類,比如JavaScript中的Array,Number等類,PHP中也有很多這種類,比如Directory,stdClass,Exception等類,同時一些標準擴展比如PDO等擴展中也會定義一些類,PHP中類是不允許重復定義的,所以在編寫代碼時不允許定義已經存在的類。

同時PHP中有一些特殊的類:self,staticparent,相信讀者對這self和parent都比較熟悉了,而static特殊類是PHP5.3才引入的。

PHP中的static關鍵字非常多義:

● 在函數體內的修飾變量的static關鍵字用于定義靜態局部變量。

● 用于修飾類成員函數和成員變量時用于聲明靜態成員。

● (PHP5.3)在作用域解析符(::)前又表示靜態延遲綁定的特殊類。

這個關鍵字修飾的意義都表示"靜態",在PHP手冊中提到self,parent和static這幾個關鍵字,但實際上除了static是關鍵字以外,其他兩個均不是關鍵字,在手冊的關鍵字列表中也沒有這兩個關鍵字,要驗證這一點很簡單:

<?php[var_dump](https://www.php.net/var_dump)(self); // -> string(4) "self"

上面的代碼并沒有報錯,如果你把error_reporting(E_ALL)打開,就能看到實際是什么情況了:運行這段代碼會出現“ Notice: Use of undefined constant self - assumed 'self'“,也就是說PHP把self當成一個普通常量了,嘗試未定義的常量會把產量本身當成一個字符串,例如上例的”self",不過同時會出一個NOTICE,這就是說self這個標示符并沒有什么特殊的。

<?php[define](https://www.php.net/define)('self',"stdClass");[echo](https://www.php.net/echo) self; // stdClass

不同語言中的關鍵字的意義會有些區別,Wikipedia上的解釋是: 具有特殊含義的標示符或者單詞,從這個意義上說$this也算是一個關鍵字,但在PHP的關鍵字列表中并沒有。 PHP的關鍵字和C/C++一樣屬于保留字(關鍵字),關鍵字用于表示特定的語法形式,例如函數定義,流程控制等結構。 這些關鍵字有他們的特定的使用場景,而上面提到的self和parent并沒有這樣的限制。

self,parent,static類

前面已經說過self的特殊性。self是一個特殊類,它指向當前類,但只有在類定義內部才有效,但也并不一定指向類本身這個特殊類,比如前面的代碼,如果放在類方法體內運行,echo self; 還是會輸出常量self的值,而不是當前類,它不止要求在類的定義內部,還要求在類的上下文環境,比如 new self()的時候,這時self就指向當前類,或者self::$static_varible,self::CONSTANT類似的作用域解析符號(::),這時的self才會作為指向本身的類而存在。

同理parent也和self類似。下面先看看在在類的環境下的編譯吧$PHP_SRC/Zend/zend_language_parser.y:

class_name_reference:        class_name                      { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }    |   dynamic_class_name_reference    { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_fetch_class(&$$, &$1 TSRMLS_CC); };

在需要獲取類名時會執行zend_do_fetch_class()函數:

void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC){    // ...    opline->opcode = ZEND_FETCH_CLASS;    if (class_name->op_type == IS_CONST) {        int fetch_type;         fetch_type = zend_get_class_fetch_type(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);        switch (fetch_type) {            case ZEND_FETCH_CLASS_SELF:            case ZEND_FETCH_CLASS_PARENT:            case ZEND_FETCH_CLASS_STATIC:                SET_UNUSED(opline->op2);                opline->extended_value = fetch_type;                zval_dtor(&class_name->u.constant);                break;            default:                zend_resolve_class_name(class_name, &opline->extended_value, 0 TSRMLS_CC);                opline->op2 = *class_name;                break;        }    } else {        opline->op2 = *class_name;    }    // ...}

上面省略了一些無關的代碼,重點關注fetch_type變量。這是通過zend_get_class_fetch_type()函數獲取到的。

int zend_get_class_fetch_type(const char *class_name, uint class_name_len){    if ((class_name_len == sizeof("self")-1) &&        !memcmp(class_name, "self", sizeof("self")-1)) {        return ZEND_FETCH_CLASS_SELF;    } else if ((class_name_len == sizeof("parent")-1) &&        !memcmp(class_name, "parent", sizeof("parent")-1)) {        return ZEND_FETCH_CLASS_PARENT;    } else if ((class_name_len == sizeof("static")-1) &&        !memcmp(class_name, "static", sizeof("static")-1)) {        return ZEND_FETCH_CLASS_STATIC;    } else {        return ZEND_FETCH_CLASS_DEFAULT;    }}

前面的代碼是Zend引擎編譯類相關操作的代碼,下面就到執行階段了,self,parent等類的指向會在執行時進行獲取,找到執行opcode為ZEND_FETCH_CLASS的執行函數:

zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC){    zend_class_entry **pce;    int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;    int silent       = (fetch_type & ZEND_FETCH_CLASS_SILENT) != 0;     fetch_type &= ZEND_FETCH_CLASS_MASK; check_fetch_type:    switch (fetch_type) {        case ZEND_FETCH_CLASS_SELF:            if (!EG(scope)) {                zend_error(E_ERROR, "Cannot access self:: when no class scope is active");            }            return EG(scope);        case ZEND_FETCH_CLASS_PARENT:            if (!EG(scope)) {                zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");            }            if (!EG(scope)->parent) {                zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");            }            return EG(scope)->parent;        case ZEND_FETCH_CLASS_STATIC:            if (!EG(called_scope)) {                zend_error(E_ERROR, "Cannot access static:: when no class scope is active");            }            return EG(called_scope);        case ZEND_FETCH_CLASS_AUTO: {                fetch_type = zend_get_class_fetch_type(class_name, class_name_len);                if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) {                    goto check_fetch_type;                }            }            break;    }     if (zend_lookup_class_ex(class_name, class_name_len, use_autoload, &pce TSRMLS_CC) == FAILURE) {        if (use_autoload) {            if (!silent && !EG(exception)) {                if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {                    zend_error(E_ERROR, "Interface '%s' not found", class_name);                } else {                    zend_error(E_ERROR, "Class '%s' not found", class_name);                }                }            }        }        return NULL;    }    return *pce;}

從這個函數就能看出端倪了,當需要獲取self類的時候,則將EG(scope)類返回,而EG(scope)指向的正是當前類。如果時parent類的話則從去EG(scope)->parent也就是當前類的父類,而static獲取的時EG(called_scope),分別說說EG宏的這幾個字段,前面已經介紹過EG宏,它可以展開為如下這個結構體:

struct _zend_executor_globals {    // ...    zend_class_entry *scope;    zend_class_entry *called_scope; /* Scope of the calling class */    // ...} struct _zend_class_entry {    char type;    char *name;    zend_uint name_length;    struct _zend_class_entry *parent;}#define struct _zend_class_entry zend_class_entry

其中的zend_class_entry就是PHP中類的內部結構表示,zend_class_entry有一個parent字段,也就是該類的父類。在EG結構體中的中called_scope會在執行過程中將當前執行的類賦值給called_scope,例如如下代碼:

<?phpclass A {    public [static](https://www.php.net/static) funcA() {        [static](https://www.php.net/static)::funcB();    }} class B {    public [static](https://www.php.net/static) funcB() {        [echo](https://www.php.net/echo)  "B::funcB()";    }} B::funcA();

代碼B::funcA()執行的時候,實際執行的是B的父類A中定義的funcA函數,A::funcA()執行時當前的類(scope)指向的是類A,而這個方法是從B類開始調用的,called_scope指向的是類B,static特殊類指向的正是called_scope,也就是當前類(觸發方法調用的類),這也是延遲綁定的原理。

以上就是PHP保留類及特殊類的詳細內容,更多請關注 其它相關文章!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97精品国产97久久久久久春色| 久久精品精品电影网| 久久国产精品亚洲| 成人xvideos免费视频| 少妇激情综合网| 国产性猛交xxxx免费看久久| 综合国产在线视频| 国产精品www色诱视频| 欧美丰满片xxx777| www.久久撸.com| 欧美日韩第一页| 91久久精品一区| 伊人久久综合97精品| www.亚洲男人天堂| 亚洲国产成人精品久久久国产成人一区| 国产日韩精品在线播放| 久久精品影视伊人网| 2020久久国产精品| 亚洲人成网站色ww在线| 中文字幕一区二区精品| 日韩av综合网| 国产精品丝袜久久久久久不卡| 91精品国产乱码久久久久久久久| 色老头一区二区三区| 日韩经典中文字幕在线观看| 国产精品日韩一区| 亚洲人成在线播放| 91精品国产自产在线| 亚洲精品日韩久久久| 一区二区欧美在线| 亚洲欧洲美洲在线综合| 这里精品视频免费| 韩日精品中文字幕| 91午夜在线播放| 色爱av美腿丝袜综合粉嫩av| 欧美性猛交xxxx| 色综合色综合久久综合频道88| 国产欧美一区二区| 亚洲午夜精品视频| 国产一区二区三区久久精品| 国产精品高精视频免费| 亚洲精品国产品国语在线| 5252色成人免费视频| 国产亚洲成av人片在线观看桃| 91网在线免费观看| 久久久久免费精品国产| 国产精品久久久久久久一区探花| 亚洲国产精品系列| 国产精品免费视频久久久| 黑人巨大精品欧美一区二区三区| 茄子视频成人在线| 久久久精品久久| 96精品视频在线| 在线电影欧美日韩一区二区私密| 亚洲视频在线免费看| 亚洲丁香婷深爱综合| 欧美乱大交xxxxx另类电影| 日韩av在线免播放器| 日韩精品一区二区视频| 色综合伊人色综合网| 欧美国产精品va在线观看| 美女精品视频一区| 亚洲男人的天堂在线| 成人午夜一级二级三级| 欧美成人午夜影院| 亚洲激情在线视频| 亚洲欧美制服综合另类| 在线看福利67194| 午夜免费在线观看精品视频| 亚洲成人激情视频| 久久视频中文字幕| 亚洲一区999| 欧美视频一二三| 精品人伦一区二区三区蜜桃免费| 亚洲欧美日韩精品久久奇米色影视| 亚洲精品免费一区二区三区| 91日韩在线播放| 动漫精品一区二区| 国产精品aaaa| 九九久久综合网站| 国产成人一区二区三区| 久久九九免费视频| 欧美一级淫片aaaaaaa视频| 国产日韩精品在线| 国模视频一区二区三区| 国产91精品久久久| 欧美性猛交xxxx久久久| 久久免费精品日本久久中文字幕| 成人网欧美在线视频| 国产精品美女免费看| 国产91精品黑色丝袜高跟鞋| 国产成人精品电影| 亚洲精品国产成人| 久久久久亚洲精品成人网小说| 精品欧美激情精品一区| 国产精品亚洲视频在线观看| 欧美国产日韩视频| 成人黄色片网站| 亚洲精品成人久久| 色青青草原桃花久久综合| 欧美国产亚洲视频| 国产精品美女免费视频| 91久久国产精品91久久性色| 色先锋资源久久综合5566| 在线精品播放av| 亚洲精品一区久久久久久| 久久久在线视频| 国产精品9999| 欧美野外猛男的大粗鳮| 亚洲男人av电影| 国产精品久久久久久一区二区| 亚洲精品中文字幕女同| 久久久www成人免费精品| 欧美色道久久88综合亚洲精品| 欧美中文在线观看国产| 久久91精品国产| 国产v综合ⅴ日韩v欧美大片| 久久亚洲精品小早川怜子66| 精品一区二区三区三区| 92福利视频午夜1000合集在线观看| 久久久久中文字幕2018| 国产精品久久久久久久久久99| 在线成人激情黄色| 超碰精品一区二区三区乱码| 国产精品一区二区在线| 成人免费大片黄在线播放| 亚洲tv在线观看| 久久777国产线看观看精品| 日韩中文视频免费在线观看| 川上优av一区二区线观看| 日韩在线小视频| 久久久久久69| 欧洲一区二区视频| 国产精品美女久久| 国产主播喷水一区二区| 免费av在线一区| 成人福利网站在线观看11| 国产视频精品免费播放| 欧美另类69精品久久久久9999| 综合网日日天干夜夜久久| 欧美日韩中文字幕在线视频| 日韩av在线天堂网| 成人午夜激情免费视频| 国产精品一区=区| 色老头一区二区三区在线观看| 91精品国产综合久久香蕉| 久久天天躁狠狠躁老女人| 伊人一区二区三区久久精品| 精品亚洲夜色av98在线观看| 欧美与欧洲交xxxx免费观看| 亚洲最大福利网| 欧美激情亚洲一区| 欧美成aaa人片在线观看蜜臀| 欲色天天网综合久久| 欧美激情乱人伦一区| 精品国产91久久久久久| 欧美日韩中文在线观看| 久久久久久久久久国产| 欧美国产精品人人做人人爱| 日韩精品视频在线观看网址| 91丝袜美腿美女视频网站| 成人妇女免费播放久久久| 伊人伊成久久人综合网小说| 色综合久综合久久综合久鬼88|