マニュアルを見ると、define で定義された定数のみが許可されます:
スカラーと null のみが許可されます。スカラーのタイプは、整数、浮動小数点、文字列、またはブール値です。 定数値のタイプを resource として定義することもできますが、これはお勧めできません。不明な状況が発生する可能性があります。
今日phpのソースコードを読んで、defineの2番目のパラメータが実際にはオブジェクトになり得ることがわかりました。
最初に例を投稿します:
コードをコピーします コードは次のとおりです:
class A {
Public function __toString() {
Return 'bar';
}
}
$a = new A();
define('foo', $a);
echo foo;
// 出力バー
次に、php での define の実装方法を見てみましょう:
コードをコピーします コードは次のとおりです以下に続きます:
ZEND_FUNCTION(define)
{
char *name;
int name_len;
zval *val;
zval *val_free = NULL;
zend_bool non_cs = 0;
int case_sensitive = CONST_CS;
zend_constant c;
/ /受け取る3 つのパラメータ、string、zval、bool
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {
return;
}
}
//大文字と小文字が区別されます
if(non_cs) {
case_sensitive = 0;
}
// クラス定数を定義するとエラーが報告されます
if (zend_memnstr(name, "::", sizeof(":: ") - 1, name + name_len )) {
zend_error(E_WARNING, "クラス定数を定義または再定義できません");
RETURN_FALSE;
case Is_long: s case is_double:
case is_string:
case is_Bool:
case is_resource:
case is_null:
case is_object:
if (! Val_free) {
i f (z_OBJ_HT_P (Val)-& gt; get) {
val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC); );
> cast_object(val、val_free、is_string tsrmls_cc)==成功){
| scalar値 "); value);
if ( val_free) {
zval_ptr_dtor(&val_free) } c.flags = case_sensitive;
;
。
repeat で始まり、goto ステートメント T_T も使用しているループに注意してください。
このコードの機能は次のとおりです。
int、float、string、bool、resource、null の場合、これらの値は直接使用されます。実際に定義されている定数
object の場合、オブジェクトを上記の 6 つのタイプのいずれかに変換する必要があります (変換後もオブジェクトである場合は、変換を続行します)
オブジェクトを 6 つのタイプのいずれかに変換するには?コードの観点からは、2 つのメソッドがあります:
コードをコピーします コードは次のとおりです:
if (Z_OBJ_HT_P(val)->get) {
val_free = val = Z_OBJ_HT_P(val) )->get(val TSRMLS_CC);
gotorepeat;
}
// __toString() メソッドが Cast_object で呼び出されます
else if (Z_OBJ_HT_P(val)->cast_object) {
ALLOC_INIT_ZVAL(val_free);
if (Z_OBJ_HT_P(val)- >cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {
val = val_free;
Break;
}
}
1, Z_OBJ_HT_P(val)-> マクロ展開後に取得(*val ).value.obj.handlers->get
2, Z_OBJ_HT_P(val)->cast_object、マクロ展開後は (*val).value.obj.handlers->cast_object
handlers です多くの構造体を含む関数ポインター。具体的な定義については、_zend_object_handlers を参照してください。この構造体の関数ポインタは、オブジェクト属性の読み取り/変更、オブジェクト メソッドの取得/呼び出しなど、オブジェクトを操作するために使用されます。get や Cast_object もその中に含まれます。
一般オブジェクトの場合、PHP は標準の Cast_object 関数 zend_std_cast_object_tostring を提供します。コードは php-src/zend/zend-object-handlers.c にあります:
コードをコピーします コードは次のとおりです:
ZEND_API int zend_std_cast_object_tostring( zval *readobj, zval *writeobj, int type TSRMLS_DC) /*{{ _P(readobj) '' ' ' s ' ' s ‐ ‐ ‐ ‐‐‐‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐ 、&retval) || EG(例外))) {
…デフォルトの Cast_object では、クラス内で __tostring メソッドを見つけてそれを呼び出します...
最初の例に戻り、define('foo', $a) とします。が A のインスタンスであり、__toString がクラス A で定義されている場合、foo 定数は実際には toString の戻り値 bar と等しくなります。
http://www.bkjia.com/PHPjc/825008.html
www.bkjia.com
true
http://www.bkjia.com/PHPjc/825008.html
技術記事
マニュアルを見ると、define で定義された定数のみが許可されます: スカラーと null のみが許可されます。スカラーのタイプは、整数、浮動小数点、文字列、またはブール値です。 定数値の型を resource として定義することも可能です...