PHP: リソースのデータ型の例の詳細な説明

怪我咯
リリース: 2023-03-07 15:52:01
オリジナル
18305 人が閲覧しました

リソースのデータ型とは何ですか?

リソースデータ型は PHP4 で導入されました。 Resource は、開いているファイル、データベース接続、グラフィックス キャンバス領域などの外部リソースへの参照を保持する特殊な変数タイプです。

リソースは、特殊な機能を通じて作成および使用されます。

PHPでのリソース変数の使用

$fp = fopen("test.txt", "rw");  
  
var_dump($fp);  
  
fclose($fp);
ログイン後にコピー

出力結果: タイプ(ストリーム)のリソース(5)

数字5: リソースIDが5であることを示します。具体的な意味は後で紹介します。

stream: リソースタイプ名。

リソースID

カーネルは、登録されたリソース変数をハッシュテーブルに保存し、リソースが配置されているハッシュテーブル内のキーをリソースIDとして使用します。

つまり、実際には、PHP のリソース変数には実際には整数が格納されており、HashTable 内の対応するリソースはこの ID を通じて検索されます。

#define Z_RESVAL(zval)          (zval).value.lval  
#define Z_RESVAL_P(zval)        Z_RESVAL(*zval)  
#define Z_RESVAL_PP(zval)       Z_RESVAL(**zval)
ログイン後にコピー

上記のマクロは、リソース変数に値を割り当てるためにカーネル内の ZE によって使用される API であり、実際に整数変数への代入であることがわかります。

リソースタイプ名

リソースタイプを区別するには、定義するリソースのタイプ名を定義する必要があります。

#define MY_RES_NAME "my_resource" //资源类型名称,PHP通过var_dump打印资源变量时会看到这个名称  
static int my_resource_descriptor;  
  
ZEND_MINIT_FUNCTION(jinyong)  
{  
    my_resource_descriptor = zend_register_list_destructors_ex(NULL, NULL, MY_RES_NAME, module_number);//向内核中注册新的资源类型  
}
ログイン後にコピー

ZEND_MINIT_FUNCTION(jinyong) は、PHP が SAPI としてメモリにロードされるときに、すべての拡張機能の ZEND_MINIT_FUNCTION を実行します (たとえば、Apache の mod_php5 拡張機能)。

その中で、jinyongは現在の拡張機能の名前です。例えば、この時の拡張機能の名前はjinyongです

理解を容易にするために、初期化時に新しいリソースタイプをカーネルに登録する拡張機能と考えます。

リソース変数の作成

リソースタイプが正常に登録され、区別されたタイプ名がリソースに定義されました。このリソースの変数が使用できるようになりました。

PHP で fopen 関数を実装します:

PHP_FUNCTION(my_fopen)  
{  
    zval *res;  
  
    char *filename, *mode;  
      
    int filename_strlen, mode_strlen;  
  
    FILE *fp;  
      
    if(zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "s|s",  &filename, &filename_strlen, &mode, &mode_strlen) == FAILURE){  
        RETURN_FALSE;  
    }  
  
    //此处省略了对参数的有效性验证  
    fp = fopen(filename, mode);  
  
    ZEND_REGISTER_RESOURCE(res, fp, my_resource_descriptor);//向全局变量&EG(regular_list)中注册资源变量,并将对应HashTable的ID赋值给res  
  
    RETURN_RESOURCE(res);//向PHP返回资源变量  
}
ログイン後にコピー

ここでは、PHP で my_fopen という名前の関数が定義されています。 my_fopen(string $file_name, string $mode)

は、PHP で fclose 関数を実装します。

PHP_FUNCTION(my_fclose)  
{  
    zval *res;  
      
    FILE *fp;  
  
    if(zend_parse_parameters(ZEND_NUM_ARGS TSRMS_CC, "r", &res) == FAILURE){  
        RETURN_FALSE;  
    }  
  
    if(Z_TYPE_P(res) == IS_RESOURCE){//判断变量类型是否是资源类型  
        zend_hash_index_del(&EG(regular_list), Z_RESVAL_P(res));//EG就类似于PHP中的$_GLOBALS。在全局资源变量regular_list中删除对应ID的资源  
    }else{  
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "参数必须是资源类型变量");  
        RETURN_FALSE;  
    }  
  
    RETURN_TRUE;  
}
ログイン後にコピー

は、PHP で my_fclose という名前の関数を定義します。 my_fclose($resource)

PHP

my_fwrite($fp, "aaTest");  
  
var_dump($fp);  
  
my_fclose($fp);  
  
var_dump($fp);
ログイン後にコピー

のカスタム拡張機能のメソッドを使用すると、リソースを正常に開閉できます。

リソースを解放する

PHP4 Zend エンジンにはリソースカウントシステムが導入されているため、(Java と同様に) リソースが参照されなくなったことを自動的に検出できます。この場合、このリソースによって使用されているすべての外部リソースは、ガベージ コレクション システムによって解放されます。したがって、結果解放関数を使用して手動でメモリを解放する必要がほとんどありません。

注: 永続的なデータベース接続は特別であり、ガベージ コレクション システムによって破棄されません。

次のセクションでは、2つの特殊なデータ型のうち、「null値(null)」について説明します。

以上がPHP: リソースのデータ型の例の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート