国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

php是如何找到要實(shí)例的對(duì)象的
PHPz
PHPz 2017-04-10 16:24:58
0
7
395

比如我有個(gè)test對(duì)象,首先先實(shí)例對(duì)象,然后對(duì)象在實(shí)例化的后面,這個(gè)時(shí)候?yàn)槭裁催€會(huì)找的到對(duì)象?

$test = new Test();
echo $test->run();

class Test{
    public function run(){
        return 'run---';
    }
}

上面代碼是怎么運(yùn)行的,php怎么找的到test對(duì)象的?

PHPz
PHPz

學(xué)習(xí)是最好的投資!

reply all(7)
阿神

你應(yīng)該明白任何解釋器都不是直接解釋源代碼的(雖然你可以這么做),而是經(jīng)過(guò)"預(yù)處理",之后,在執(zhí)行這個(gè)預(yù)處理的結(jié)果.雖然說(shuō)是解釋器
比如你寫

echo "Hello world";
exit;
!#$%^&*()error

按照你理解的邏輯,可能php的解釋器是現(xiàn)在才開(kāi)始掃描這個(gè)源碼,它會(huì)打印出Hello world的,但卻給你一個(gè)PHP Parse error: syntax error, 的異常.
奇怪,可見(jiàn),源代碼在執(zhí)行前經(jīng)過(guò)了一次檢查,這些檢查包括但不限于語(yǔ)法檢測(cè),php的源碼是經(jīng)過(guò)處理的,你所定義的Test已經(jīng)存在了.也就是說(shuō),所謂的解釋器,基本上都存在"偽編譯"的過(guò)程,所謂動(dòng)態(tài)是指,你每一次請(qǐng)求都需要經(jīng)過(guò)這樣的處理,對(duì)Java而言,這些工作需要你手動(dòng)指定,編譯OK的class,繼續(xù)交給虛擬機(jī)執(zhí)行.

下面是在鳥(niǎo)哥的博客里面找到的執(zhí)行流程簡(jiǎn)化,解釋器其實(shí)是在解釋Opcode(這也是APC存在的基礎(chǔ)):

  1. 詞法分析, 去掉注釋, 空白, 得到TOKEN

  2. 語(yǔ)法分析, 在這個(gè)過(guò)程中生成Opcode array (op_array)

  3. 解釋執(zhí)行, 執(zhí)行op_array, 一條一條的解釋執(zhí)行Opline(SWITCH, CALL, GOTO)

大家講道理

PHP 解釋器是個(gè) C 程序。
它是解釋型語(yǔ)言,所以無(wú)需編譯,但這個(gè)編譯指的是『編譯成二進(jìn)制文件』。
但是從腳本到結(jié)果,中間還是有一系列過(guò)程的。

語(yǔ)言本身只是為了更符合人的習(xí)慣,PHP 解釋器最終執(zhí)行的是 opcode。

從從 php 腳本到 opcodes 的的過(guò)程在 PHP5 中是:

Lexing:詞法掃描分析,將源文件轉(zhuǎn)換成 token 流;
Parsing:語(yǔ)法分析,在此階段生成 op arrays。

PHP7 中在語(yǔ)法分析階段不再直接生成 op arrays,而是先生成 AST,所以過(guò)程多了一步:

Lexing:詞法掃描分析,將源文件轉(zhuǎn)換成 token 流;
Parsing:語(yǔ)法分析,從 token 流生成抽象語(yǔ)法樹(shù);
Compilation:從抽象語(yǔ)法樹(shù)生成 op arrays。

上面的 lexing,也就是詞法分析,PHP 用的是 re2c,parsing 也就是語(yǔ)法分析,PHP 用的是bison。
lexing 做一些符號(hào)替換,狀態(tài)記錄的東西。
parsing 會(huì)去掃描語(yǔ)法,然后調(diào)用相應(yīng)的處理函數(shù),比如 zend_do_begin_class_declaration 之類的函數(shù)。當(dāng)然這是 PHP5,PHP7 它會(huì)先去調(diào) zend_ast_create 之類的。

接下來(lái) PHP5 中 parsing 調(diào)的相應(yīng)的處理函數(shù)就會(huì)將語(yǔ)句轉(zhuǎn)換成 opcode,將變量存在內(nèi)存中,函數(shù)名、類名存在符號(hào)表中。
PHP7 中會(huì)有 compile 相關(guān)的函數(shù)去分析抽象語(yǔ)法樹(shù),然后得到和上面相同的結(jié)果。

這樣你的變量、類、函數(shù)都在內(nèi)存中準(zhǔn)備就緒了,你的賦值語(yǔ)句、函數(shù)調(diào)用語(yǔ)句都已經(jīng)變成了順序排列的一條一條的 opcode array了。

然后就是執(zhí)行了。會(huì)有一個(gè) excute 相關(guān)的函數(shù)來(lái)一條一條的執(zhí)行 opcode,得到的就是你要的結(jié)果。

所以你的類雖然寫在下面,但是完全可以被找到的。

上面說(shuō)的這些過(guò)程,對(duì)應(yīng)的 PHP 解釋器中的文件分別是:

zend_language_scanner.l
zend_language_parser.y
zend_ast.c (PHP7)
zend_compile.c
zend_excute.c

如果有 C 語(yǔ)言的底子,嘗試從另外一個(gè)層面去了解會(huì)更簡(jiǎn)單。

大家講道理

php是解釋型語(yǔ)言, 不用像編譯型語(yǔ)言(c)那樣提前聲明函數(shù)定義。

迷茫

運(yùn)行之前電腦會(huì)把整個(gè)php代碼加載到內(nèi)存中吧。然后再去查找調(diào)用。。
我是才學(xué)一個(gè)月的小白。。不知道對(duì)不對(duì)

大家講道理

代碼會(huì)放在內(nèi)存中的代碼區(qū),程序運(yùn)行的時(shí)候調(diào)用,所以在你代碼中的順序沒(méi)有關(guān)系,但建議便于閱讀,實(shí)例放在前面。

Peter_Zhu

別高興得太早,如果它繼承另一個(gè)類(include),就要放在下面了,php是個(gè)奇葩

Peter_Zhu

我覺(jué)得大家解釋的都僅僅是原理,沒(méi)有解釋道這題的根本,這道問(wèn)題的意思是問(wèn)為什么把類定義到調(diào)用類的后面也可以,按照常理來(lái)說(shuō)是類定義在要調(diào)用的前面才能查找得到。
我來(lái)解釋一下這個(gè)問(wèn)題吧,首先,定義了類,不調(diào)用,是沒(méi)有意義的,要調(diào)用,就必須要實(shí)例化,上面提到的opcode執(zhí)行機(jī)制,這個(gè)是對(duì)的,那么我說(shuō)的原因基于這個(gè),也就是說(shuō)php在執(zhí)行的時(shí)候進(jìn)行預(yù)編譯,那么編譯的時(shí)候把執(zhí)行的數(shù)據(jù)放到內(nèi)存,其存放方式和我們寫代碼的時(shí)候是不一樣的,php把每種類型的數(shù)據(jù)放到不同的位置,比如把類放到堆,也就是說(shuō),你這個(gè)類,不管定義在前面和后面,執(zhí)行程序的時(shí)候,相當(dāng)于是忽略你的定義的(因?yàn)樵陬A(yù)編譯階段被移動(dòng)到了堆),那么只有在執(zhí)行到實(shí)例化具體的類的時(shí)候,才會(huì)去堆里查找有沒(méi)有定義這個(gè)類,定義了按照堆里定義的類數(shù)據(jù)進(jìn)行實(shí)例化,然后執(zhí)行。

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template