ホームページ バックエンド開発 PHPチュートリアル PHP 拡張機能と埋め込み -- PHP 拡張機能の配列とハッシュ テーブル 1_PHP チュートリアル

PHP 拡張機能と埋め込み -- PHP 拡張機能の配列とハッシュ テーブル 1_PHP チュートリアル

Jul 13, 2016 am 10:42 AM
埋め込む 拡大する

PHP では、配列の基礎となる実装はハッシュ テーブルであり、キーと値の形式で表示されます。 PHP の Zend エンジンには、さまざまなハッシュ テーブル操作のためのハッシュ テーブルを操作するための特別な API があります。


創造

ハッシュテーブルの場合、初期化方法は毎回同じであり、次の関数zend_hash_initによって完了します:

int zend_hash_init(HashTable *ht, uint nSize,
    hash_func_t pHashFunction,
    dtor_func_t pDestructor, zend_bool persistent)
ログイン後にコピー
ここで、ht はハッシュ テーブルへのポインタであり、既存のハッシュテーブル変数を参照できます。新しいハッシュテーブルのメモリを申請することもできます。一般的な方法は次のとおりです:

ALLOC_HASHTABLE(ht)、ht = emalloc(sizeof(HashTable)); と同等。

nSizeは、事前にメモリに適用されると考えられるハッシュテーブルの最大要素数です。 2 の指数倍数でない場合は、nSize = pow(2, ceil(log(nSize, 2))) の式に従って増加します。たとえば、5 が与えられた場合、8 まで増加します。これは、メモリ管理の比較のためのものである必要があります。 便利なメカニズムが採用されています。

pHashFunction は以前のバージョンの zend eigine 関数に属しており、新しいバージョンでは常に NULL に設定できます。

pDestructor は、ハッシュ テーブル内の要素が削除されたときに呼び出されるメソッド (zend_hash_del() zend_hash_update()) の入り口を指します。これは、対応するコールバック関数です。 Method_name 関数が指定されている場合、関数が実装されるとき:

void メソッド名(void *pElement)
pElement は削除された要素を指します

persistent は、永続的なハッシュ テーブルであるかどうかを示すフラグです。永続データはリクエストから独立しており、RSHUTDOWN 中にログアウトされません。ただし、1 に設定すると、ht はメモリを適用するときに pemalloc() を使用する必要があります。

例: 各 PHP リクエスト ライフ サイクルでsymbol_table を初期化すると、zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0); が表示されます。 設定を解除すると、ハッシュ テーブルに格納されている対応する zval* が zval_ptr_dtor() に送信されて破棄されます。


人口:
ハッシュ テーブルにデータを挿入および更新するための主な関数は 4 つあります:

int zend_hash_add(HashTable *ht, char *arKey, uint nKeyLen,
                void *pData, uint nDataSize, void **pDest);
int zend_hash_update(HashTable *ht, char *arKey, uint nKeyLen,
                void *pData, uint nDataSize, void **pDest);
int zend_hash_index_update(HashTable *ht, ulong h,
                void *pData, uint nDataSize, void **pDest);
int zend_hash_next_index_insert(HashTable *ht,
                void *pData, uint nDataSize, void **pDest);
ログイン後にコピー
最初の 2 つの関数は、php の $foo['bar'] = 'barvalue' などの文字列インデックスを持つデータをハッシュテーブルに追加し、その後拡張子に追加します。

zend_hash_add(fooHashTbl, "bar", sizeof("bar"), &barZval, sizeof(zval*), NULL);

対応するキー値と対応するテーブル値がハッシュテーブルに追加されます。

追加と更新の唯一の違いは、キーがすでに存在する場合、追加は失敗することです。

最後の 2 つの関数は、ht に数値インデックス データを追加することです。

zend_hash_next_index_insert() 関数はインデックス値パラメーターを必要としませんが、次の数値インデックス値をそれ自体で直接計算します。

次の要素の数値インデックス値を自分で取得したい場合は、zend_hash_next_free_element() を通じてインデックスを取得することもできます。

ulong nextid = zend_hash_next_free_element(ht);

zend_hash_index_update(ht, nextid, &data, sizeof(data), NULL);
上記のコードは次と同等です:

zend_hash_next_index_insert(HashTable *ht, &data,sizeof(data),NULL).

pDest パラメータは、新しく追加された要素のアドレス値を保存するために使用できます。



思い出してください:

を見つけてください 一般的に、ハッシュ テーブル内のデータを取得するには 2 つの方法があります:

りー

これは、以下の例でより明確に見ることができます:


int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength,
                                        void **pData);
int zend_hash_index_find(HashTable *ht, ulong h, void **pData);
ログイン後にコピー
ハッシュ テーブルの値を取得することに加えて、いくつかの要素の存在を知ることがより重要な場合もあります:

int zend_hash_exists(HashTable *ht, char *arKey, uint nKeyLen);
int zend_hash_index_exists(HashTable *ht, ulong h);
ログイン後にコピー
分别针对字符串索引和数字的索引。返回的是1和0.
if (zend_hash_exists(EG(active_symbol_table),
                                "foo", sizeof("foo"))) {//确定活动的符号表中是否存在foo变量
    /* $foo is set */
} else {
    /* $foo does not exist */
}
ログイン後にコピー


Quick Population and Recall 当需要对同一个字符串的key进行许多操作的时候比如先检测有没有,然后插入再修改之类的,可以使用zend_get_hash_value来进行提速。这个函数的返回值可以和quick系列的函数使用,从而达到加速的目的。因为不需要再重复计算字符串的散列值,而是直接使用已有的散列值
ulong zend_get_hash_value(char *arKey, uint nKeyLen);
ログイン後にコピー
用这个返回值传给下面的quick系列函数就可以达到加速的目的:
int zend_hash_quick_add(HashTable *ht,
    char *arKey, uint nKeyLen, ulong hashval,
    void *pData, uint nDataSize, void **pDest);
int zend_hash_quick_update(HashTable *ht,
    char *arKey, uint nKeyLen, ulong hashval,
    void *pData, uint nDataSize, void **pDest);
int zend_hash_quick_find(HashTable *ht,
    char *arKey, uint nKeyLen, ulong hashval, void **pData);
int zend_hash_quick_exists(HashTable *ht,
    char *arKey, uint nKeyLen, ulong hashval);
ログイン後にコピー

下面给出了一个在两个哈希表之间进行数据拷贝的例子:
void php_sample_hash_copy(HashTable *hta, HashTable *htb,
                    char *arKey, uint nKeyLen TSRMLS_DC)
{
    ulong hashval = zend_get_hash_value(arKey, nKeyLen);//获得用来加速的散列值hashval
    zval **copyval;
    if (zend_hash_quick_find(hta, arKey, nKeyLen,
                hashval, (void**)©val) == FAILURE) {//首先要在hta table里面找到相应的元素,并且存储在copyval中。
        /* arKey doesn't actually exist */
        return;
    }
    /* The zval* is about to be owned by another hash table */
    (*copyval)->refcount__gc++;//相应zval*变量的引用次数+1
    zend_hash_quick_update(htb, arKey, nKeyLen, hashval,
                copyval, sizeof(zval*), NULL);//把从hta中拿来的copyval放在htb里面。
}
ログイン後にコピー

注意并没有zend_hash_del函数。

Copy and Merging 有三个方法可以进行数据的拷贝,先来看第一个:
typedef void (*copy_ctor_func_t)(void *pElement);
void zend_hash_copy(HashTable *target, HashTable *source,
            copy_ctor_func_t pCopyConstructor,
            void *tmp, uint size);
ログイン後にコピー
在source中的每个元素都会被拷贝到target中.通过pCopyConstructor的处理可以使得在拷贝变量的时候对这些变量的ref_count进行加一的操作。target中原有的与source中索引位置相同的元素会被替换掉,而其他的元素则会被保留。
tmp这里放NULL,低版本才会用到。
size的话代表每个元素的大小,一般是sizeof(zval *)。
void zend_hash_merge(HashTable *target, HashTable *source,
            copy_ctor_func_t pCopyConstructor,
            void *tmp, uint size, int overwrite);
ログイン後にコピー
主要是多了一个overwrite的参数,如果非0,那就跟copy一样,如果是0,那就对于已经存在的元素就不会进行复制了。

下面的这一组函数允许使用一个归并的检查进行选择性的复制:
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht,
    void *source_data, zend_hash_key *hash_key, void *pParam);
void zend_hash_merge_ex(HashTable *target, HashTable *source,
            copy_ctor_func_t pCopyConstructor, uint size,
            merge_checker_func_t pMergeSource, void *pParam);
ログイン後にコピー
pMergeSource回调函数使得可以选择性的进行合并,而不是全部合并,这个给人的感觉有点像c语言里面快速排序函数所留的函数入口,可以决定排序的方式。
下面给出了一个应用的例子:
zend_bool associative_only(HashTable *ht, void *pData,
            zend_hash_key *hash_key, void *pParam)
{
    /* True if there's a key, false if there's not */
    return (hash_key->arKey && hash_key->nKeyLength);//字符串类型的key,因为存在nKeyLength
}
void merge_associative(HashTable *target, HashTable *source)
{
    zend_hash_merge_ex(target, source, zval_add_ref,
                sizeof(zval*), associative_only, NULL);
}
ログイン後にコピー





















www.bkjia.comtruehttp://www.bkjia.com/PHPjc/635039.htmlTechArticle在php中,数组的底层实现就是哈希表,都是以key-value的形式出现的。在php的Zend引擎中,针对不同的哈希表操作,都有着专门的对哈希表进行...
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の 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 拡張機能 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 の SNMP 拡張機能を使用するにはどうすればよいですか? PHP の SNMP 拡張機能を使用するにはどうすればよいですか? Jun 02, 2023 am 10:22 AM

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

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

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

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 を使用できます。

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 をインストールします。

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

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

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 および WebDriver 拡張機能: ユーザーのクリックと入力アクションをシミュレートする方法 PHP および WebDriver 拡張機能: ユーザーのクリックと入力アクションをシミュレートする方法 Jul 07, 2023 pm 05:10 PM

PHP および WebDriver 拡張機能: ユーザーのクリックと入力操作をシミュレートする方法 近年、Web アプリケーションの急速な発展に伴い、自動テストの重要性がますます高まっています。自動テストでは、ユーザー操作のシミュレーションが重要なリンクであり、これによりアプリケーションをより正確にテストおよび検証できるようになります。 PHP 開発では、通常、SeleniumWebDriver を使用して自動テストを実装します。 SeleniumWebDriver は、シミュレートできる強力なツールです。

See all articles