目次
PHPの基礎となる動作メカニズムと原理、PHPの基礎となる動作メカニズム
ホームページ バックエンド開発 PHPチュートリアル PHP の基礎となる動作メカニズムと原則、PHP の基礎となる動作メカニズム_PHP チュートリアル

PHP の基礎となる動作メカニズムと原則、PHP の基礎となる動作メカニズム_PHP チュートリアル

Jul 12, 2016 am 09:04 AM
動作機構

PHPの基礎となる動作メカニズムと原理、PHPの基礎となる動作メカニズム

作者:nowamagic
ログイン後にコピー
リーリー

PHPは簡単だと言われていますが、使いこなすのは簡単ではありません。それを使用できることに加えて、その根本的な動作原理を知る必要もあります。

PHP は Web 開発に適した動的言語です。具体的には、C言語を使用して多数のコンポーネントを実装するソフトウェアフレームワークです。より狭い意味で見ると、強力な UI フレームワークと考えることができます。

PHP の基礎となる実装を理解する目的は何ですか?動的言語をうまく使用するには、まずメモリ管理とフレームワーク モデルを理解する必要があります。拡張された開発を通じて、より強力な機能を実現し、プログラムのパフォーマンスを最適化できます。

1. PHPの設計コンセプトと機能

  • マルチプロセス モデル: PHP はマルチプロセス モデルであるため、異なるリクエストは互いに干渉せず、1 つのリクエストの失敗がサービス全体に影響を与えることはありません。もちろん、PHP の時代の発展により。はすでにマルチスレッド モデルをサポートしています。

  • 型が弱い言語: C/C++、Java、C#、その他の言語とは異なり、PHP は型が弱い言語です。変数の型は最初は決定されず、暗黙的または明示的な型変換が行われるため、Web 開発では非常に便利で効率的です。詳細については、「変数」で説明します。に詳しく記載されています。

  • エンジン (Zend) + コンポーネント (ext) モードは、内部結合を軽減します。

  • 中間層 (sapi) は Web サーバーと PHP を分離します。

  • 構文はシンプルで柔軟であり、あまり多くの仕様はありません。欠点があるとスタイルが混在しますが、プログラマがどんなに下手でも、突飛すぎて全体の状況を危険にさらすようなプログラムは書きません。

2. PHPの4層システム

PHP のコアアーキテクチャは以下のとおりです:

PHP の基礎となる動作メカニズムと原則、PHP の基礎となる動作メカニズム_PHP チュートリアル

写真からわかるように、PHP は下から上への 4 層システムです:

  • Zend エンジン: Zend は完全に純粋な C で実装されており、PHP のコア部分です。PHP コード (字句解析、構文解析、その他のコンパイル プロセス) を実行可能なオペコード処理に変換し、対応する処理メソッドを実装し、基本的なデータ構造 (次のような) を実装します。 hashtable、oo)、メモリの割り当てと管理、および外部呼び出しに対応する API メソッドの提供がすべての中核であり、すべての周辺機能が Zend を中心に実装されています。

  • 拡張機能: Zend エンジンを中心に、拡張機能はコンポーネントベースの方法でさまざまな基本サービスを提供します。一般的な組み込み関数 (配列シリーズなど)、標準ライブラリなどはすべて拡張機能を通じて実装されます。機能拡張やパフォーマンスの最適化などを実現するために、必要に応じて拡張機能を追加します(たとえば、現在 Tieba で使用されている PHP 中間層やリッチテキスト解析などが拡張機能の代表的な適用例です)。

  • Sapi: Sapi の正式名は、サーバー アプリケーション プログラミング インターフェイスです。Sapi は、PHP が周辺データと対話できるようにするための一連のフック関数を使用します。これは、PHP の非常にエレガントで成功した設計です。 sapi を使用すると、PHP 自体が上位層のアプリケーションから切り離され、分離されます。PHP は、異なるアプリケーションとの互換性を考慮する必要がなくなり、アプリケーション自体も独自の特性に応じて異なる処理方法を実装できます。

  • 上位層アプリケーション: これは、私たちが通常作成する PHP プログラムです。Web サーバーを介して Web アプリケーションを実装したり、コマンド ラインでスクリプト モードで実行したりするなど、さまざまな Sapi メソッドを通じてさまざまなアプリケーション モードを取得できます。

PHP が車だとすると、車のフレームは PHP そのものであり、Zend は車のエンジンであり、Ext の下にあるさまざまなコンポーネントは車の車輪とみなすことができ、車はそう考えることができます。さまざまな種類の道路を走行し、PHP プログラムを実行することで車が道路を走行します。したがって、高性能エンジン + 適切なホイール + 適切なトラックが必要です。

3.サピ

前述したように、Sapi を使用すると、外部アプリケーションが一連のインターフェイスを通じて PHP とデータを交換し、さまざまなアプリケーションの特性に応じて特定の処理メソッドを実装できるようになります。

  • apache2handler: これは、Apache を Web サーバーとして使用し、mod_PHP モードで実行する場合の処理​​方法であり、現在最も広く使用されています。

  • cgi: これは、有名な fastcgi プロトコルである Web サーバーと PHP の間の別の直接対話方法であり、近年、fastcgi+PHP がますます使用されており、非同期 Web サーバーでサポートされている唯一の方法でもあります。

  • cli: コマンドラインによって呼び出されるアプリケーションモード

4. PHPの実行プロセスとオペコード

まず、PHP コードを実行するプロセスを見てみましょう。

PHP の基礎となる動作メカニズムと原則、PHP の基礎となる動作メカニズム_PHP チュートリアル

从图上可以看到,PHP实现了一个典型的动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用C实现的,因此最终调用的也都是C的函数,实际上,我们可以把PHP看做是一个C开发的软件。

PHP的执行的核心是翻译出来的一条一条指令,也即opcode。

Opcode是PHP程序执行的最基本单位。一个opcode由两个参数(op1,op2)、返回值和处理函数组成。PHP程序最终被翻译为一组opcode处理函数的顺序执行。

常见的几个处理函数:

<p>ZEND_ASSIGN_SPEC_CV_CV_HANDLER : 变量分配 ($a=$b)</p>
<p>ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER:函数调用</p>
<p>ZEND_CONCAT_SPEC_CV_CV_HANDLER:字符串拼接 $a.$b</p>
<p>ZEND_ADD_SPEC_CV_CONST_HANDLER: 加法运算 $a+2</p>
<p>ZEND_IS_EQUAL_SPEC_CV_CONST:判断相等 $a==1</p>
<p>ZEND_IS_IDENTICAL_SPEC_CV_CONST:判断相等 $a===1</p>


ログイン後にコピー

5. HashTable — 核心数据结构

HashTable是zend的核心数据结构,在PHP里面几乎并用来实现所有常见功能,我们知道的PHP数组即是其典型应用,此外,在zend内部,如函数符号表、全局变量等也都是基于hash table来实现。

PHP的hash table具有如下特点:

  • 支持典型的key->value查询

  • 可以当做数组使用

  • 添加、删除节点是O(1)复杂度

  • key支持混合类型:同时存在关联数组合索引数组

  • Value支持混合类型:array (“string”,2332)

  • 支持线性遍历:如foreach

Zend hash table实现了典型的hash表散列结构,同时通过附加一个双向链表,提供了正向、反向遍历数组的功能。其结构如下图:

PHP の基礎となる動作メカニズムと原則、PHP の基礎となる動作メカニズム_PHP チュートリアル

可以看到,在hash table中既有key->value形式的散列结构,也有双向链表模式,使得它能够非常方便的支持快速查找和线性遍历。

  • 散列结构:Zend的散列结构是典型的hash表模型,通过链表的方式来解决冲突。需要注意的是zend的hash table是一个自增长的数据结构,当hash表数目满了之后,其本身会动态以2倍的方式扩容并重新元素位置。初始大小均为8。另外,在进行key->value快速查找时候,zend本身还做了一些优化,通过空间换时间的方式加快速度。比如在每个元素中都会用一个变量nKeyLength标识key的长度以作快速判定。

  • 双向链表:Zend hash table通过一个链表结构,实现了元素的线性遍历。理论上,做遍历使用单向链表就够了,之所以使用双向链表,主要目的是为了快速删除,避免遍历。Zend hash table是一种复合型的结构,作为数组使用时,即支持常见的关联数组也能够作为顺序索引数字来使用,甚至允许2者的混合。

  • PHP关联数组:关联数组是典型的hash_table应用。一次查询过程经过如下几步(从代码可以看出,这是一个常见的hash查询过程并增加一些快速判定加速查找。):

<p>getKeyHashValue h;</p>
<p>index = n & nTableMask;</p>
<p>Bucket *p = arBucket[index];</p>
<p>while (p) {</p>
<p>   if ((p->h == h) & (p->nKeyLength == nKeyLength)) {</p>
<p>       RETURN p->data;  </p>
<p>   }</p>
<p>   p=p->next;</p>
<p>}</p>


ログイン後にコピー
  • PHP索引数组:索引数组就是我们常见的数组,通过下标访问。例如 $arr[0],Zend HashTable内部进行了归一化处理,对于index类型key同样分配了hash值和nKeyLength(为0)。内部成员变量nNextFreeElement就是当前分配到的最大id,每次push后自动加一。正是这种归一化处理,PHP才能够实现关联和非关联的混合。由于push操作的特殊性,索引key在PHP数组中先后顺序并不是通过下标大小来决定,而是由push的先后决定。例如 $arr[1] = 2; $arr[2] = 3;对于double类型的key,Zend HashTable会将他当做索引key处理

6. PHP变量

PHP是一门弱类型语言,本身不严格区分变量的类型。PHP在变量申明的时候不需要指定类型。PHP在程序运行期间可能进行变量类型的隐示转换。和其他强类型语言一样,程序中也可以进行显示的类型转换。PHP变量可以分为简单类型(int、string、bool)、集合类型(array resource object)和常量(const)。以上所有的变量在底层都是同一种结构 zval。

Zval是zend中另一个非常重要的数据结构,用来标识并实现PHP变量,其数据结构如下:

PHP の基礎となる動作メカニズムと原則、PHP の基礎となる動作メカニズム_PHP チュートリアル

Zval主要由三部分组成:

  • type:指定了变量所述的类型(整数、字符串、数组等)

  • refcount&is_ref:用来实现引用计数(后面具体介绍)

  • value:核心部分,存储了变量的实际数据

Zvalue是用来保存一个变量的实际数据。因为要存储多种类型,所以zvalue是一个union,也由此实现了弱类型。

PHP变量类型和其实际存储对应关系如下:

<p>IS_LONG   -> lvalue</p>
<p>IS_DOUBLE -> dvalue</p>
<p>IS_ARRAY  -> ht</p>
<p>IS_STRING -> str</p>
<p>IS_RESOURCE -> lvalue</p>


ログイン後にコピー

引用计数在内存回收、字符串操作等地方使用非常广泛。PHP中的变量就是引用计数的典型应用。Zval的引用计数通过成员变量is_ref和ref_count实现,通过引用计数,多个变量可以共享同一份数据。避免频繁拷贝带来的大量消耗。

在进行赋值操作时,zend将变量指向相同的zval同时ref_count++,在unset操作时,对应的ref_count-1。只有ref_count减为0时才会真正执行销毁操作。如果是引用赋值,则zend会修改is_ref为1。

PHP变量通过引用计数实现变量共享数据,那如果改变其中一个变量值呢?当试图写入一个变量时,Zend若发现该变量指向的zval被多个变量共享,则为其复制一份ref_count为1的zval,并递减原zval的refcount,这个过程称为“zval分离”。可见,只有在有写操作发生时zend才进行拷贝操作,因此也叫copy-on-write(写时拷贝)

对于引用型变量,其要求和非引用型相反,引用赋值的变量间必须是捆绑的,修改一个变量就修改了所有捆绑变量。

整数、浮点数是PHP中的基础类型之一,也是一个简单型变量。对于整数和浮点数,在zvalue中直接存储对应的值。其类型分别是long和double。

从zvalue结构中可以看出,对于整数类型,和c等强类型语言不同,PHP是不区分int、unsigned int、long、long long等类型的,对它来说,整数只有一种类型也就是long。由此,可以看出,在PHP里面,整数的取值范围是由编译器位数来决定而不是固定不变的。

对于浮点数,类似整数,它也不区分float和double而是统一只有double一种类型。

在PHP中,如果整数范围越界了怎么办?这种情况下会自动转换为double类型,这个一定要小心,很多trick都是由此产生。

和整数一样,字符变量也是PHP中的基础类型和简单型变量。通过zvalue结构可以看出,在PHP中,字符串是由由指向实际数据的指针和长度结构体组成,这点和c++中的string比较类似。由于通过一个实际变量表示长度,和c不同,它的字符串可以是2进制数据(包含),同时在PHP中,求字符串长度strlen是O(1)操作。

在新增、修改、追加字符串操作时,PHP都会重新分配内存生成新的字符串。最后,出于安全考虑,PHP在生成一个字符串时末尾仍然会添加

常见的字符串拼接方式及速度比较:

假设有如下4个变量:$strA=‘123’; $strB = ‘456’; $intA=123; intB=456;

现在对如下的几种字符串拼接方式做一个比较和说明:

<p>$res = $strA.$strB和$res = &ldquo;$strA$strB&rdquo;</p>
<p>这种情况下,zend会重新malloc一块内存并进行相应处理,其速度一般</p>
<p>$strA = $strA.$strB</p>
<p>这种是速度最快的,zend会在当前strA基础上直接relloc,避免重复拷贝</p>
<p>$res = $intA.$intB</p>
<p>这种速度较慢,因为需要做隐式的格式转换,实际编写程序中也应该注意尽量避免</p>
<p>$strA = sprintf (&ldquo;%s%s&rdquo;,$strA.$strB);</p>


ログイン後にコピー

这会是最慢的一种方式,因为sprintf在PHP中并不是一个语言结构,本身对于格式识别和处理就需要耗费比较多时间,另外本身机制也是malloc。不过sprintf的方式最具可读性,实际中可以根据具体情况灵活选择。

PHP的数组通过Zend HashTable来天然实现。

foreach操作如何实现?对一个数组的foreach就是通过遍历hashtable中的双向链表完成。对于索引数组,通过foreach遍历效率比for高很多,省去了key->value的查找。count操作直接调用HashTable->NumOfElements,O(1)操作。对于’123’这样的字符串,zend会转换为其整数形式。$arr[‘123’]和$arr[123]是等价的

资源类型变量是PHP中最复杂的一种变量,也是一种复合型结构。

PHP的zval可以表示广泛的数据类型,但是对于自定义的数据类型却很难充分描述。由于没有有效的方式描绘这些复合结构,因此也没有办法对它们使用传统的操作符。要解决这个问题,只需要通过一个本质上任意的标识符(label)引用指针,这种方式被称为资源。

在zval中,对于resource,lval作为指针来使用,直接指向资源所在的地址。Resource可以是任意的复合结构,我们熟悉的mysqli、fsock、memcached等都是资源。

如何使用资源:

  • 注册:对于一个自定义的数据类型,要想将它作为资源。首先需要进行注册,zend会为它分配全局唯一标示。

  • 获取一个资源变量:对于资源,zend维护了一个id->实际数据的hash_tale。对于一个resource,在zval中只记录了它的id。fetch的时候通过id在hash_table中找到具体的值返回。

  • リソースの破壊: リソースのデータ型は多様です。 Zend 自体にはそれを破壊する方法はありません。したがって、ユーザーはリソースを登録する際に破棄機能を提供する必要があります。リソースの設定が解除されると、zend は対応する関数を呼び出して破棄を完了します。グローバルリソーステーブルからも削除してください。

リソースは、それを参照しているすべての変数がスコープ外になった後だけでなく、リクエストが終了して新しいリクエストが生成された後でも、長期間存続することができます。これらのリソースは、特に破棄されない限り、SAPI のライフサイクル全体にわたって存続するため、永続リソースと呼ばれます。多くの場合、永続リソースによりパフォーマンスがある程度向上します。たとえば、一般的な mysql_pconnect では、永続リソースは pemalloc を通じてメモリを割り当て、リクエストが終了しても解放されないようにします。

zend の場合、2 つの区別はありません。

ローカル変数とグローバル変数は PHP でどのように実装されますか?リクエストの場合、PHP はいつでも 2 つのシンボル テーブル (symbol_table と active_symbol_table) を参照でき、前者はグローバル変数を維持するために使用されます。後者は、現在アクティブな変数シンボル テーブルを指すポインターです。プログラムが関数に入ると、zend はシンボル テーブル x をそれに割り当て、active_symbol_table を a に指します。このようにして、グローバル変数とローカル変数の区別が行われます。

変数値の取得: PHP のシンボル テーブルは hash_table を通じて実装され、取得時に対応する zval がテーブルから検索され、識別子に従って返されます。

関数でグローバル変数を使用する: 関数では、明示的に global を宣言することでグローバル変数を使用できます。 active_symbol_tableのsymbol_tableに同じ名前の変数への参照を作成します。symbol_tableに同じ名前の変数が存在しない場合は、それが最初に作成されます。

www.bkjia.com本当http://www.bkjia.com/PHPjc/1071497.html技術記事 PHP の基礎となる動作メカニズムと原理、PHP の基礎となる動作メカニズム 著者: nowamagic リンク: http://www.nowamagic.net/librarys/veda/detail/102 PHP はシンプルと言われますが、簡単ではありません。マスター…
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPコアの動作メカニズムと実装原理の詳細な説明 PHPコアの動作メカニズムと実装原理の詳細な説明 Nov 08, 2023 pm 01:15 PM

PHP は、Web 開発で頻繁に使用される、人気のあるオープン ソースのサーバー側スクリプト言語です。動的データを処理し、HTML 出力を制御できますが、これを実現するにはどうすればよいでしょうか?次に、この記事では、PHP の中核となる動作メカニズムと実装原理を紹介し、具体的なコード例を使用してその動作プロセスを詳しく説明します。 PHP ソース コードの解釈 PHP ソース コードは C 言語で書かれたプログラムです。コンパイル後、実行可能ファイル php.exe が生成されます。Web 開発で使用される PHP の場合、通常は A を通じて実行されます。

徹底分析:Go言語のゴルーチンの本質と動作仕組み 徹底分析:Go言語のゴルーチンの本質と動作仕組み Mar 12, 2024 pm 03:39 PM

Go 言語では、ゴルーチンはコードの断片を同時に実行するために使用される軽量のスレッドです。従来のスレッドと比較して、ゴルーチンはより効率的で、メモリ消費量が少なく、起動速度が速くなります。この記事では、Go 言語のゴルーチンの性質と動作メカニズムを深く分析し、読者の理解を深めるために具体的なコード例を示します。 1. Goroutine の本質 Go 言語では、Goroutine は Go ランタイムによって管理される軽量オブジェクトです。

Swoole のコルーチンの動作メカニズムを調べる Swoole のコルーチンの動作メカニズムを調べる Jun 13, 2023 am 10:27 AM

SwooleはPHPをベースにしたコルーチンフレームワークであり、非同期IO性能が優れています。 Swoole のコアはコルーチンです。コルーチンはスレッドよりも軽量な同時実行メカニズムであり、同じスレッド内でタスクを切り替えて同時実行を実現できます。この記事では、Swoole のコルーチンの動作メカニズムについて説明します。 1. コルーチンの概念 コルーチンはマイクロスレッドとしても知られ、スレッドよりもきめの細かい同時実行メカニズムです。コルーチンとスレッドの違いは、コルーチンはタイム スライスのローテーションを通じてタスクの切り替えを実装するのに対し、スレッドはオペレーティング システムのスケジューラによって切り替えられることです。

Zend Framework ミドルウェアの動作メカニズムと原理を理解する Zend Framework ミドルウェアの動作メカニズムと原理を理解する Jul 28, 2023 pm 01:49 PM

ZendFramework ミドルウェアの動作メカニズムと原理を理解する インターネットの継続的な発展に伴い、Web アプリケーションの複雑さも増しています。これらの問題を解決するために、ミドルウェアの概念が登場しました。ミドルウェアは非常に重要なテクノロジーであり、ZendFramework でも広く使用されています。この記事では、ZendFrameworkミドルウェアの動作メカニズムと原理を紹介し、サンプルコードを通じて詳しく説明します。まず、ミドルウェアとは何でしょうか?ミドルウェアとは一種の

ApacheTomcatの動作原理と動作メカニズムを分析する ApacheTomcatの動作原理と動作メカニズムを分析する Jan 24, 2024 am 10:14 AM

ApacheTomcat は、Apache Software Foundation によって開発および保守されているオープン ソースの JavaServlet コンテナです。これは、Java アプリケーション開発用の最も人気のあるサーブレット コンテナの 1 つであり、エンタープライズ レベルの Web アプリケーションの展開に広く使用されています。この記事では、Apache Tomcat の原理と動作メカニズムを詳細に分析し、具体的なコード例を示します。 Tomcat のアーキテクチャ Apache Tomcat は、複数のモジュールで構成されるコンポーネントベースのアーキテクチャを採用しています。

Tomcatミドルウェアの動作メカニズムと内部動作原理の詳細な分析 Tomcatミドルウェアの動作メカニズムと内部動作原理の詳細な分析 Dec 28, 2023 pm 01:20 PM

Tomcat ミドルウェアの動作メカニズムと内部動作の解読 概要: Tomcat は、Java Web アプリケーションで広く使用されているオープン ソースの HTTP サーバーおよびサーブレット コンテナです。 HTTP リクエストの処理、Web アプリケーションの管理、サーブレットのライフサイクル管理などの豊富な機能を提供します。この記事では、Tomcat のコア コンポーネント、リクエスト処理プロセス、クラス ロード メカニズム、Servl の習得など、Tomcat ミドルウェアの動作メカニズムと内部動作原理を深く調査します。

Linux カーネル機能の詳細な説明: 5 つの主要な部分の包括的な解釈 Linux カーネル機能の詳細な説明: 5 つの主要な部分の包括的な解釈 Mar 21, 2024 am 08:18 AM

Linux カーネルの機能を詳しく解説: 主要 5 つの部分を徹底解説 Linux カーネルは、コンピューターのハードウェア リソースを管理し、プロセス管理、ファイル システム、デバイス ドライバーなどの機能を提供するオープン ソースのオペレーティング システム カーネルです。 Linux カーネルは多くの異なる部分で構成されており、それぞれが特定の機能と責任を持っています。この記事では、Linux カーネルの 5 つの主要な部分を包括的に説明し、読者の理解を助ける具体的なコード例を示します。 1. プロセス管理 プロセス管理は Linux カーネルの中核機能の 1 つであり、次の役割を果たします。

コードを書いてPHP8の動作仕組みを深く理解する方法 コードを書いてPHP8の動作仕組みを深く理解する方法 Sep 12, 2023 pm 02:25 PM

コードを書いて PHP8 の動作メカニズムを深く理解する方法 はじめに: PHP8 は、PHP プログラミング言語の次のメジャー バージョンであり、多くの新機能と改善が加えられています。 PHP8 を最大限に活用するには、プログラマはその動作メカニズムを深く理解する必要があります。コードを記述するプロセスは、PHP8 の内部動作をより深く理解するのに役立ちます。この記事では、PHP8の動作メカニズムを深く理解するのに役立つコーディングテクニックをいくつか紹介します。 1. PHP8 の新機能を理解する コードを記述する前に、まず PHP8 を理解する必要があります。

See all articles