ホームページ バックエンド開発 PHPチュートリアル phpの拡張と埋め込み--php内部変数_PHPチュートリアル

phpの拡張と埋め込み--php内部変数_PHPチュートリアル

Jul 13, 2016 pm 05:18 PM
内部 埋め込む 拡大する

以前、PHP の内部ライフサイクルと Zend エンジンのスレッド セーフティ メカニズムについて紹介しましたが、この記事では主に PHP の内部変数がどのように実装されるかを紹介します。

これらの実装方法を理解すると、PHP の作成、特に PHP 拡張機能の開発に非常に役立つと感じます。


php は C に比べて型指定が比較的緩やかな言語で、変数を使用する前に型を指定する必要がなく、変数を直接使用できます。これを実現するために、PHP はデータ型の定義に関して何らかの作業を行う必要があります。

データ型:

最も基本的なタイプは zval または Zend Value と呼ばれ、Zend/zend.h ヘッダー ファイルで定義されます。 typedef struct _zval_struct {
zvalue_value 値;
zend_uint refcount;
zend_uchar タイプ;
zend_uchar is_ref;
zval; このうち、zvalue_value は次のように定義されます。 typedef Union _zvalue_value {
長い lval;
ダブル dval;
構造体{
char *val;
イントレン;
} str;
ハッシュテーブル *ht;
zend_object_value obj;
zvalue_value; これは共用体です。共用体を使用する場合は 2 つの可能性があります。1 つはすべての変数がメモリ空間を共有する場合、もう 1 つは n からいずれかの型を選択する必要がある場合です。
Zend では 8 つの基本的なデータ型が定義されています。これらの 8 つは基本的に他の言語でも見られるため、より特殊な型についてのみ説明します。 IS_NULL: 非値IS_BOOL: IS_LONGIS_DOUBLEIS_STRING: 割り当てられるスペースは長さ + 1 である必要がありますIS_ARRAY: PHP の配列は実際には、ラベルとデータを含むハッシュテーブルですIS_OBJECT: 配列に基づいて、メソッド、アクセス修飾子、ドメイン定数、特殊文字が追加されますイベント ハンドラー IS_RESOURCE: たとえば、ファイル ハンドルまたは mysql ハンドルは zval の型に格納され、zvalue_value と個別に対応します。 以下に 2 つの型判定関数の比較があることに注意してください。 リーリー そして れーれー
最初のコードは C で書かれ、2 番目のコードは PHP スタイルで書かれています。 Zend ヘッダー ファイルには zval 処理用のマクロが多数用意されていることに注意してください。ここでは Z_TYPE_P(foo) を使用します。それぞれ zval と zval** に対応する Z_TYPE() と Z_TYPE_PP() もあります php_printf() は printf に基づいており、SAPI および PHP 出力メカニズム用にいくつかの最適化を行います。


データ値

さまざまなタイプの zval の値は、いくつかのマクロを通じて取得できます。 BVAL(): ブールLVAL(): longDVAL(): double この関数は Z_TYPE を使用して、3 つの異なる zval 型の型判定を実行します。次に、対応する値抽出マクロを使用して値を取得します。 れーれー
文字列の処理は少し特殊です。値と長さをそれぞれ読み取るために 2 つのマクロ Z_STRVAZ_STRLEN が必要です。これは、文字と長さで構成される文字列タイプの定義からもわかります。 リーリー
配列へのアクセスには、ARRVAL シリーズ: Z_ARRVAL(zv)、Z_ARRVAL_P(pzv)、Z_ARRVAL_PP(ppzv) を使用します。 PHP ソース コードの一部のバージョンでは、HASH_OF() は Z_ARRVAL_P と同等ですが、このマクロは徐々に使用されなくなりました。
オブジェクトの場合: OBJ_HANDLE は、オブジェクト ハンドル識別子を返します。 OBJ_HT ハンドル テーブル OBJCE クラス定義 OBJPROP 属性ハッシュ テーブル OBJ_HANDLER は、OBJ_HT 内の特定の処理メソッドを操作します リソースの場合は、マクロ RESVAL を直接使用します。

データ作成:

想要创造一个变量并分配空间的malloc(sizeof(zval))在php这里并不可行。应该使用MAKE_STD_ZVAL(pzv), 它对空间的分配进行了优化,并且会自动的初始化refCount(表示这个变量被引用的次数)和is_ref(是否是强制引用)这两个性质。注意它的输入是一个指针.
ALLOC_INIT_ZVAL()也可以进行初始化,不同之处在于把zval*的值设为了NULL.
在设置不同类型的值的时候有很多形式,左边是比较简略的形式,右侧则是展开的形式: ZVAL_NULL(pvz); Z_TYPE_P(pzv) = IS_NULL;
ZVAL_BOOL(pzv, b); Z_TYPE_P(pzv) = IS_BOOL;
Z_BVAL_P(pzv) = b ? 1 : 0;
ZVAL_TRUE(pzv); ZVAL_BOOL(pzv, 1);
ZVAL_FALSE(pzv); ZVAL_BOOL(pzv, 0);
ZVAL_LONG(pzv, l); Z_TYPE_P(pzv) = IS_LONG;
Z_LVAL_P(pzv) = l;
ZVAL_DOUBLE(pzv, d); Z_TYPE_P(pzv) = IS_DOUBLE;
Z_DVAL_P(pzv) = d;
对于字符串的处理要特殊一些,提供了一个单独的参数dup. 这个参数决定了是否创建一个字符串的副本.举个例子 zval * pzva; ZVAL_STRING(pzval,"hello world",1); 由于“hello_world”是一个常量字符串,直接对它进行操作显然不合适,所以把dup设为1的话,会自动的给它创建一个副本,然后再赋给pzval. 这使得整个过程更加简洁。

ZVAL_STRINGL(pzv,str,len,dup); Z_TYPE_P(pzv) = IS_STRING;
Z_STRLEN_P(pzv) = len;
if (dup) {
Z_STRVAL_P(pzv) =
estrndup(str, len + 1);
} else {
Z_STRVAL_P(pzv) = str;
}
ZVAL_STRING(pzv, str, dup); ZVAL _STRINGL(pzv, str,
strlen(str), dup); 注意dup如果设为1的话就是申请新的空间并且拷贝内容,而不是一个shaddow copy。 ZVAL_RESOURCE(pzv, res); Z_TYPE_P(pzv) = IS_RESOURCE;
Z_RESVAL_P(pzv) = res;


数据的存储

数据的存储都在符号表中。 symbol table,每当创建一个新的变量的时候,Zend都保存这个值到这个内部的数组中去。 符号表在RINIT之前创建,在RSHUTDOWN之后销毁。
当用户空间的函数或对象方法被调用的时候,会创建一个新的符号表,生命与函数执行时间相同。 在Zend/zend_gblobals.h中定义了两个元素:
struct _zend_executor_globals {
    ...
    HashTable symbol_table;
    HashTable *active_symbol_table;
    ...
};
ログイン後にコピー

通过EG(symbol_table) 的方式可以访问符号表。感觉跟$GLOBALS似的。 注意到EG(symbol_table)这个宏返回的不是指针,必须加上&。 下面的这个对比非常的有趣: In PHP:
<?php $foo = 'bar'; ?>
ログイン後にコピー
针对这段php的代码,C中一共做了如下这些事:
In C:
{
    zval *fooval;
    MAKE_STD_ZVAL(fooval); //首先分配空间,设置变量
    ZVAL_STRING(fooval, "bar", 1); //然后赋值,创建一个copy,你不能直接操作常字符串
    ZEND_SET_SYMBOL(EG(active_symbol_table), "foo", fooval); // 在符号表中注册,foo是一个label
}
ログイン後にコピー
所谓active_symbol_table指的是程序执行当前的符号表,在进入一个函数之后,会有它自己对应的符号表,就类似于C中针对一个函数自己的栈空间。而当退出了函数之后,它的符号表会被销毁,这时候又回到了下面这个状态: EG(active_symbol_table) == &EG(symbol_table), 这个时候并没有进入函数。

数据的获取: 在获取数据的时候,比较多的是使用zend_hash_find()函数:

{
    zval **fooval;
    if (zend_hash_find(EG(active_symbol_table),
                       "foo", sizeof("foo"),
                       (void**)&fooval) == SUCCESS) {
        php_printf("Got the value of $foo!");
    } else {
        php_printf("$foo is not defined.");
    }
}
ログイン後にコピー
这个函数首先查找符号表,找到名字为“foo”的变量,然后返回到fooval中。下面着重解释两个问题:

为什么要声明一个zval ** fooval 然后还要通过&fooval并且转换为(void **)的形式?为什么要用sizeof("foo") 对第一个问题,要考虑到我们寻找的目标是一个zval*,所以要把它看作一个整体。利用这种写法可以避免编译告警。 第二个问题,使用sizeof(label)主要是为了表示字符串常量label的尾部,这里使用4也是可以的,但是通用性不够。

数据转换: 仅仅是说一下有这个功能,比如convert_to_string(zval *value)可以把zval转换为字符串。


以上就是php内部变量的一些介绍,为了能够区分不同的类型、设置获取变量值以及在符号表中增加和查找变量,这些知识必不可少。




www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/621628.html技術記事以前に PHP の内部ライフサイクルと Zend エンジンのスレッド セーフティ メカニズムについて紹介しましたが、この記事では主に 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 の SNMP 拡張機能を使用するにはどうすればよいですか? PHP の SNMP 拡張機能を使用するにはどうすればよいですか? Jun 02, 2023 am 10:22 AM

PHP の SNMP 拡張機能は、PHP が SNMP プロトコルを介してネットワーク デバイスと通信できるようにする拡張機能です。この拡張機能を使用すると、CPU、メモリ、ネットワークインターフェイスなどのネットワークデバイスの構成情報やルータ、スイッチなどの情報を簡単に取得および変更できます。また、スイッチングデバイスのポートなどの制御操作も実行できます。この記事では、SNMP プロトコルの基本知識、PHP の SNMP 拡張機能をインストールする方法、PHP で SNMP 拡張機能を使用してネットワーク デバイスを監視および制御する方法を紹介します。 1.SN

最初から最後まで: PHP 拡張機能 cURL を使用して HTTP リクエストを行う方法 最初から最後まで: PHP 拡張機能 cURL を使用して HTTP リクエストを行う方法 Jul 29, 2023 pm 05:07 PM

最初から最後まで: HTTP リクエストに php 拡張機能 cURL を使用する方法 はじめに: Web 開発では、多くの場合、サードパーティ API または他のリモート サーバーと通信する必要があります。 cURL を使用して HTTP リクエストを行うのは、一般的で強力な方法です。この記事では、PHP を使用して cURL を拡張して HTTP リクエストを実行する方法を紹介し、いくつかの実用的なコード例を示します。 1. 準備 まず、php に cURL 拡張機能がインストールされていることを確認します。コマンドラインで php-m|grepcurl を実行して確認できます。

PHP と HTML の組み合わせ: コードを埋め込むための 3 つのテクニック PHP と HTML の組み合わせ: コードを埋め込むための 3 つのテクニック Mar 06, 2024 am 08:09 AM

PHP と HTML の組み合わせは、Web 開発における一般的なテクノロジです。PHP は、HTML ファイルに動的コンテンツを埋め込み、補助機能を実装することで、Web サイトの対話性とカスタマイズ性を大幅に向上させることができます。この記事では、コードを埋め込むための 3 つのテクニックを紹介し、参考として具体的なコード例を示します。 1. PHP タグを使用してコードを埋め込む 最も一般的な方法は、PHP タグ () を使用して PHP コードを HTML ファイルに埋め込み、動的コンテンツを表示することです。たとえば、PHP を使用できます。

PHP 関数の拡張機能とサードパーティ モジュール PHP 関数の拡張機能とサードパーティ モジュール Apr 13, 2024 pm 02:12 PM

PHP 関数の機能を拡張するには、拡張機能とサードパーティのモジュールを使用できます。拡張機能は、pecl パッケージ マネージャーを通じてインストールおよび有効化できる追加の関数とクラスを提供します。サードパーティ モジュールは特定の機能を提供し、Composer パッケージ マネージャーを通じてインストールできます。実際の例には、拡張機能を使用して複雑な JSON データを解析したり、モジュールを使用してデータを検証したりすることが含まれます。

CENTOS7でmbstring拡張機能をインストールするにはどうすればよいですか? CENTOS7でmbstring拡張機能をインストールするにはどうすればよいですか? Jan 06, 2024 pm 09:59 PM

1.UncaughtError:Calltoundependentfunctionmb_strlen(); 上記のエラーが発生した場合、mbstring 拡張機能がインストールされていないことを意味します; 2. PHP インストール ディレクトリ cd/temp001/php-7.1.0/ext/mbstring に入ります 3. phpize( /usr/local/bin /phpize または /usr/local/php7-abel001/bin/phpize) コマンドを使用して、php 拡張機能 4../configure--with-php-config=/usr/local/php7-abel をインストールします。

Aurora Push 拡張機能を使用して PHP アプリケーションにバッチ メッセージ プッシュ機能を実装する方法 Aurora Push 拡張機能を使用して PHP アプリケーションにバッチ メッセージ プッシュ機能を実装する方法 Jul 25, 2023 pm 08:07 PM

Aurora Push 拡張機能を使用して PHP アプリケーションにバッチ メッセージ プッシュ機能を実装する方法 モバイル アプリケーションの開発において、メッセージ プッシュは非常に重要な機能です。 Jiguang Push は、豊富な機能とインターフェイスを提供する、一般的に使用されるメッセージ プッシュ サービスです。この記事では、Aurora Push 拡張機能を使用して、PHP アプリケーションにバッチ メッセージ プッシュ機能を実装する方法を紹介します。ステップ 1: Jiguang Push アカウントを登録し、API キーを取得する まず、Jiguang Push の公式 Web サイト (https://www.jiguang.cn/push) に登録する必要があります。

PHP の ZipArchive 拡張機能を使用するにはどうすればよいですか? PHP の ZipArchive 拡張機能を使用するにはどうすればよいですか? Jun 02, 2023 am 08:13 AM

PHP は、Web アプリケーションの開発やファイルの処理に使用できる人気のあるサーバー側言語です。 PHP 用の ZipArchive 拡張機能は、PHP で zip ファイルを操作するための強力なツールです。この記事では、PHP の ZipArchive 拡張機能を使用して zip ファイルを作成、読み取り、変更する方法について説明します。 1. ZipArchive 拡張機能をインストールする ZipArchive 拡張機能を使用する前に、拡張機能がインストールされていることを確認する必要があります。インストール方法は以下のとおりです。 1. インストールします。

PHP の POSIX 拡張機能を使用するにはどうすればよいですか? PHP の POSIX 拡張機能を使用するにはどうすればよいですか? Jun 03, 2023 am 08:01 AM

PHP の POSIX 拡張機能は、PHP が POSIX 準拠のオペレーティング システムと対話できるようにする関数と定数のセットです。 POSIX (PortableOperatingSystemInterface) は、ソフトウェア開発者がさまざまな UNIX または UNIX 類似のオペレーティング システム上で実行できるアプリケーションを作成できるように設計された一連のオペレーティング システム インターフェイス標準です。この記事では、PHP 用の POSIX 拡張機能のインストールと使用方法を紹介します。 1. PHP の POSIX 拡張機能を次の場所にインストールします。

See all articles