基本的なPHPの知識の一部

比較的乾燥したこの部分では、独自のミネラルウォーターをご持参ください

トピックを説明するための第6条ポイント

  1. PHP運用のメカニズムと原則
  2. PHP基本となる可変データ構造
  3. の値によってPHPの割り当てCOW機能
  4. PHPのガベージコレクションメカニズム
  5. 基礎となる分析におけるPHPの配列
  6. PHPの配列関数の分類

PHP運用のメカニズムと原則

スキャン - >パース - >コンパイル - >実行 - >出力

ステップ

  • スキャニング

コードの構文と字句解析、切断された断片の内容(トークン)

  • 解決

コードスニペットは、スペースや他のコメントを選別、トークンの残りの部分は、意味のある表情に変わります

  • コンパイル

中間コードにコンパイルされた式(オペコード)

  • 実行

中間コード実行部

  • 輸出

実行結果がバッファに出力されます。

コードカッティング

$code = <<<EOF
<?php
echo 'hello world'l;
$data = 1+1;
echo $data;
EOF;

print_r(token_get_all($code));

結果

Array
(
    [0] => Array
        (
            [0] => 376
            [1] => <?php

            [2] => 1
        )

    [1] => Array
        (
            [0] => 319
            [1] => echo
            [2] => 2
        )

    [2] => Array
        (
            [0] => 379
            [1] =>
            [2] => 2
        )

    [3] => Array
        (
            [0] => 318
            [1] => 'hello world'
            [2] => 2
        )

    [4] => Array
        (
            [0] => 310
            [1] => l
            [2] => 2
        )

    [5] => ;
    [6] => Array
        (
            [0] => 379
            [1] =>

            [2] => 2
        )

    [7] => =
    [8] => Array
        (
            [0] => 379
            [1] =>
            [2] => 3
        )

    [9] => Array
        (
            [0] => 308
            [1] => 1
            [2] => 3
        )

    [10] => +
    [11] => Array
        (
            [0] => 308
            [1] => 1
            [2] => 3
        )

    [12] => ;
    [13] => Array
        (
            [0] => 379
            [1] =>

            [2] => 3
        )

    [14] => Array
        (
            [0] => 319
            [1] => echo
            [2] => 4
        )

    [15] => Array
        (
            [0] => 379
            [1] =>
            [2] => 4
        )

    [16] => ;
)

上記の情報は、次の3つの観察することができます

  1. そのようなスペース、キャリッジリターンなどのトークンIDが379であります
  2. トークン文字列
  3. 行番号

で定義されたトークンIDは、Zendのトークンに対応する内部コードでありますzend_language_parser.h

PHPの効率を向上させます

  1. 圧縮されたコード、不要なコメントや空白文字を削除する(jquery.min.js)
  2. 組み込み関数や拡張機能PHPを使用してみてください
  3. APC / XCacheと/ opcacheと、このようなPHPのオペコードキャッシュとして
  4. キャッシュの複雑で時間のかかる操作の結果
  5. 電子メールの送信など、非同期処理を同期することはできません
  • HHVMなぜ速いです

(javaのに似ている)仮想マシンを実行するために、直接PHPバイナリバイトコードに変換し、常に実行時に解決するために行っていません。

PHP基本となる可変データ構造

zvalのストレージ構造を使用して、以下のコードがZend/zend.h定義されています

typedef union _zvalue_value 
{
    /* 下面定义描述了PHP的8大数据类型 */
    long lval;               // 长整型 布尔型
    double dval;             // 浮点型 
    struct {                 // 字符串型
        char *val;
        int len;             // strlen 返回这个值
    } str;                   // NULL 类型表示本身为空 
    HashTable *ht;           // 数组使用哈希表实现 
    zend_object_value obj;   // 对象类型 
} zvalue_value;

struct  _zval_struct
{
    zvalue_value value;     /* 变量的值 */
    zend_uint refcount__gc;
    zend_uchar type;        /* 变量的类型 */
    zend_uchar is_ref__gc
};

typedef struct _zval_struct zval;

可変型定義は、次のコードがZend/zend_types.h定義されています

typedef unsigned int zend_uint;
typedef unsigned char zend_uchar;

統一を介してデータのPHP 8つの主要なタイプzvalue_valueのストレージのコモンウェルス

联合体自身为空         描述 null 
long                  描述 int bool 
double                描述 float
str                   描述 string
HashTable             描述 数字数组和关联数组
zend_object_value     描述 对象和资源

PHPの変数の型は、使用説明zend_uchar type説明

#define IS_NULL         0
#define IS_LONG         1
#define IS_DOUBLE       2
#define IS_BOOL         3
#define IS_ARRAY        4
#define IS_OBJECT       5
#define IS_STRING       6
#define IS_RESOURCE     7
#define IS_CONSTANT     8
#define IS_CONSTANT_ARRAY 9

例えば、$a=3構造は、(擬似)以下

struct {
    zvalue_value = 3;
    refcount__gc = 1;
    type = IS_LONG;
    is_ref__gc = 0;
}

$a 上記構造体へのポインタのような

の値によってPHPの割り当てCOW機能

_zval_structのデータ構造と同様に、次の二つの部材

  • zend_uint refcount__gcは、引用された回数だけ、各時間基準+1を表します
  • zend_uchar通常変数または参照変数を表しis_ref__gc

メカニズムを理解するためにコードを書くことにより、以下の引用文

ここで私はphp5.4を使用しています、あなたは可変基準xdebugのを見るためにインストールする必要があります

参照の数が0であったであろう時にphp7.2テストの使用を注意してください

インストールはXdebug ダウンロード

コンパイルされたxdebug.so

yum -y install php-devel
tar xf xdebug-2.8.0alpha1.tgz
cd xdebug-2.8.0alpha1
phpize
find /usr/ -name "php-config"
./configure  --with-php-config=/usr/bin/php-config
make && make install
ls /usr/lib64/php/modules/

設定xdebugの

php --ini
echo 'zend_extension=/usr/lib64/php/modules/xdebug.so' >> /etc/php.ini
systemctl restart php72-php-fpm.service
php -m | grep xdebug

テストコードを書きます

$a = 3;
xdebug_debug_zval('a');

輸出

A:(参照カウント= 1、is_ref = 0)= 3

  • refcount 参照番号1
  • is_ref 0は、通常の変数を示し
  • =3 図3は、値を表します

引用開始

$a = 3;
$b = $a;

xdebug_debug_zval('a');
xdebug_debug_zval('b');

輸出

A:(参照カウント= 2、is_ref = 0)= 3
B:(参照カウント= 2、is_ref = 0)= 3


新しい価値を考えます

$a = 3;
$b = $a;
$b = 5;

xdebug_debug_zval('a');
xdebug_debug_zval('b');

輸出

A:(参照カウント= 1、is_ref = 0)= 3
B:(参照カウント= 1、is_ref = 0)= 5


配信アドレス

$a = 3;
$b = &$a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');

輸出

A:(参照カウント= 2、is_ref = 1)= 3
B:(参照カウント= 2、is_ref = 1)= 3

共通可変基準変数に変数から転送is_ref


新しい価値を考えます

$a = 3;
$b = &$a;
$c = $a;

$b = 5;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
xdebug_debug_zval('c');

A:(参照カウント= 2、is_ref = 1)5 =
(参照カウント= 2、is_ref = 1)= 5:B
C:(参照カウント= 1、is_ref = 0)= 3


概要

  • 変数の値は、新しいスペースを開くリソースを節約することなく、代入形式の間で参照によって渡されます

  • 変数の値が変更された場合、それは、コピーオンライトとして知られる新しい価値、間接参照を保存するためにコピーします(COW)

  • 参照変数は、COWをトリガしません。

PHPのガベージコレクションメカニズム

ゴミは何ですか

上海の人々:あなたは何を数えるゴミ?

いいえ変数の参照、それzvalの場合、それはゴミです

?:(参照カウント= 0、is_ref = 0)= 5

なぜゴミをクリーンアップするのでしょうか?

一部の人々はそのスレッドの終了時にすべてのPHP変数を破壊するであろうと言う、近くにはすべてのリソースを処理し、ない自動の事、なぜクリーンアップする必要があります

  • リサイクルなしに処理(例えば、映画1Gなど)PHP短いハンドル複数の大きなファイルは、次のものを継続した場合、メモリのオーバーフローになり
  • PHPスクリプトは、デーモンまたは長時間実行、ないゴミがある場合は、ゆっくりとメモリオーバーフローとなり、蓄積

ゴミをクリーンアップする方法

  1. ごみを探して
  2. 取り除きます
  • ごみを探して

get_defined_vars定義されているすべての変数を表示します

基礎となるコードは、zend_globals.hすべての変数を格納するための2つのハッシュテーブルを定義します

struct _zend_executor_globals {
    ...
    HashTable *active_symbol_table; //局部变量符号表
    HashTable symbol_table;         //全局变量符号表
    ...
}

すべての定義された変数を見つけた後、どのような変数の参照番号0見つけます

struct _zval_struct{
    ...
    zend_uint refcount__gc;
    zend_uchar is_ref__gc;
    ...
}
  • 酷いです

以上のように、変数0 refcount__gcクリアランス、アイデアはPHP5.2バージョンの前に練習することです

PHP5.3使用後引用计数系统中同步周期回收アルゴリズムを削除します

実際には、新しいアルゴリズムを回復さrefcount__gcに基づいているので、なぜそれのための新しいアルゴリズムを使うのか?

refcount__gc 0はゴミでなければならない私たちを知っています

しかし、すべてのゴミrefcount__gc 0です

Refcount__gcもないスパム、以下の実験は、0 0スパムを生成することが


$a = ['a'];
$a[] = &$a; //引用自己
xdebug_debug_zval('a');

輸出

A:(参照カウント= 2、is_ref = 1)=配列(
0 =>(参照カウント= 1、is_ref = 0)= ''、
1 =>(参照カウント= 2、is_ref = 1)= ...

第二の要素:代表的な再帰...、参照番号2は、ポインタ参照変数であります

公式写真提供

画像


この時点で、$ aを削除

$a = ['a'];
$a[] = &$a;

unset($a);
xdebug_debug_zval('a'); 

出力
A:いいえ、そのようなシンボル

$ aが削除されるので、Xdebugのプリントが出てこないので、次のようにこの時間は理論が構成されているので、

(参照カウント= 1、is_ref = 1)=配列(
0 =>(参照カウント= 1、is_ref = 0)= ''、
1 =>(参照カウント= 1、is_ref = 1)= ...

画像

この時点で、このzvalのは何のシンボル(記号)が引用されていない、しかし、その独自の引用の自分は、参照カウントは1であるので、それはゴミの素晴らしい作品です

最後はスペースを取るだろうこの場合のPHPスクリプトの終わりには、自動的にクリア

だから、前5.2へのごみのアイデアのバージョンは、このケースをカバーすることはできません


参照カウントシステム同期回復サイクルアルゴリズム(システム参照カウントでの同時サイクルコレクション)

一例として、上記のコードを続行

新しいアルゴリズムの説明:

$a疑いのジャンク変数として、削除(refcount--)をシミュレートし、その後の回復をシミュレートするために、復元条件は、値があれば(++参照カウント)シミュレートされた回復参照他の変数があります

このような成功は、それは削除することができ、ゴミを復元することができません。

上記のごみ素晴らしい例:

(参照カウント= 1、is_ref = 1)=配列(
0 =>(参照カウント= 1、is_ref = 0)= ''、
1 =>(参照カウント= 1、is_ref = 1)= ...

シミュレーションを削除した後次のようになります。

(参照カウント= 0、is_ref = 1)=配列(
0 =>(参照カウント= 0、is_ref = 0)= ''、
1 =>(参照カウント= 0、is_ref = 1)= ...

その後、回復をシミュレートします:

そのようなシンボルがzvalをを取るために同様のポイントが$されていないので、それがに復元されていません

ときにクリア

上記のアルゴリズムによってスパムがエリア(のRCP)に格納される可能性があり、唯一の完全なゴミの直後にクリアされます。前提はオープンガベージコレクションであることに注意してください

二つの方法で開くガベージコレクション

  1. php.iniの下ではzend.enable_gc = Onデフォルトで有効になって

  2. よるgc_enable()gc_disable()開いたり閉じガベージコレクション

それは次のように使用することができるgc_collect_cycles()強制回復期間の機能

最後に、そんなに、実際には、唯一の関与の原則を理解する必要があり、全体のプロセスが参加するPHP開発者を必要としないと述べ、ちょうどgc_enable呼び出し()またはgc_collect_cycles()を自動的に回収することができます

基礎となる分析におけるPHPの配列

プロパティの配列を確認するには

PHPの配列の主な機能

$arr = [
    1 => 'a',
    '1' => 'b',
    1.5 => 'c',
    true => 'd',
];

print_r($arr);

アレイ

[1] => D

キーは、整数または文字列のいずれかになります

値は任意の型を指定できます

キーは、次のような特徴を持っています

  • 数値文字列を整数に変換する「1」=> 1
  • 1.3 =「1に変換、浮動小数点および整数ブール
  • 空の文字列として扱われますヌルヌル=>「」
  • キー名は、オブジェクトや配列を使用することはできません
  • 同じキー名の後ろのフロントカバー

アクセス配列の要素

  1. $のARR [キー]
  2. $ arrの{キー}

次のように5.4バージョンを使用することができた後、

function getArr(){ return [1,2,3,4]; }
echo getArr()[2];

配列要素を削除します。

$a = [1,2,3,4];
foreach ($a as $k => $v) {
    unset($a[$k]);
}

$a[] = 5;

print_r($a);

アレイ

[4] => 5

  • インデックスをリセットしません削除

アレイトラバーサル

  1. にとって
  2. foreachの
  3. あるarray_walk
  4. array_mapを
  5. 現在の和次

内部配列を達成

実装は、次の2つの構造を使用HashTableし、bucket

画像

  • ハッシュテーブルは何ですか

ハッシュテーブルは、データ構造は、キーワードによって直接メモリ記憶場所にアクセスします。

(1)、検索、挿入、変更、削除Oで完了さ:キーワードの位置が、そのようなマッピングテーブルを得るために、ハッシュ関数によって計算されます

画像

次のコード Zend/zend_types.h

typedef struct _zend_array HashTable;

struct _zend_array {
    zend_refcounted_h gc;
    union {
        struct {
            ZEND_ENDIAN_LOHI_4(
                zend_uchar    flags,
                zend_uchar    nApplyCount,
                zend_uchar    nIteratorsCount,
                zend_uchar    consistency)
        } v;
        uint32_t flags;
    } u;
    uint32_t          nTableMask; 
    Bucket           *arData;
    uint32_t          nNumUsed;
    uint32_t          nNumOfElements;
    uint32_t          nTableSize;           
    uint32_t          nInternalPointer;
    zend_long         nNextFreeElement;
    dtor_func_t       pDestructor;
};

古い構造

typedef struct _hashtable {
    uint nTableSize;
    uint nTableMask;
    uint nNumOfElements;
    ulong nNextFreeElement;
    Bucket *pInternalPointer;
    Bucket *pListHead;
    Bucket *pListTail;
    Bucket **arBuckets;
    unsigned char nApplyCount;
};
メンバー 説明
nTableSize バケットサイズ、2倍の増加に8の最小
nTableMask インデックスチューニングnTableSize-1
nNumOfElements count()関数を使用して、要素の数は、直接に返します
nNextFreeElement foreachのを使用して次のインデックス位置
pInternalPointer 現在の反復ポインタ、より高速な理由のためのよりforeachのは、現在の関数の使い方をリセット
pListHead 存储数组头部指针
pListTail 存储数组尾部指针
arBuckets 实际存储容器
arData Bucket数据
nApplyCount 记录被递归次数,防止死循环递归
typedef struct bucket
{
    ulong h;
    uint nKeyLength;
    void *pData;
    void *pDataPtr;
    struct bucket *pListNext;
    struct bucket *pListLast;
    struct bucket *pNext;
    struct bucket *pLast;
    const char *arKey;
};
成员 说明
h 对char *key进行hash后的值,或是用户指定数字索引值
nKeyLength 哈希关键字长度,若为索引数字则为0
pData 指向value 一般是用户数据的副本,若为指针数据则指向指针
pDataPtr 如果是指针数据,指针会指向真正value,上面指向此
pListNext 整个hash表下个元素
pListLast 整个hash表上个元素
pNext 同一个hash的下一个元素
pLast 同一个hash的上一个元素
arKey 保存当前key对应的字符串

画像

foreach 遍历先从 HashTable 的 pListHead -> pListNext

pNextpLast 用于hash冲突同一个hash不同个bucket之间指针

PHP数组函数分类

建议体验一下下面的函数,不用记住,只是留个印象,当你需要用的时候会联想起来的,而不用自己去实现

遍历

  • prev
  • next
  • current
  • end
  • reset
  • each

排序

  • sort
  • rsort
  • asort
  • ksort
  • krsort
  • uasort
  • uksort

查找

  • in_array
  • array_search
  • array_key_exists

分合

  • array_slice
  • array_splice
  • implode
  • explode
  • array_combine
  • array_chunk
  • array_keys
  • array_values
  • array_columns

集合

  • array_merge
  • array_diff
  • array_diff_*
  • array_intersect
  • array_intersect_*

队列/栈

  • array_push
  • array_pop
  • array_shift

其他

  • array_fill
  • array_flip
  • array_sum
  • array_reverse

再現、ソースを明記してくださいhttps://www.cnblogs.com/demonxian3/p/11327522.htmlを

おすすめ

転載: www.cnblogs.com/demonxian3/p/11327522.html