首頁>Program>source

我正在研究PHP的轉換機製,並且在將陣列轉換為物件時遇到了一个奇怪的情况

$o = (object) array('1'=>'/foo/bar');   
$o = new stdClass();
var_dump($o);

据我了解,PHP屬性必须使用与PHP變數相同的規則宣告.那就是有效的變數名以字母或下划線開頭,後跟任意 字母,數字或下划線的數量.但是,以上代碼会产生以下輸出

object(stdClass)#1 (1) {
  [1]=>
  string(8) "/foo/bar"
}

当您尝試訪問物件中的資訊時,它真的變得很奇怪。

var_dump($o->1);        // parse error
var_dump($o->{'1'});        // NULL 
var_dump(get_object_vars($o));  //array(0) { }

無論如何,是否可以获得物件中var_dump報告的資訊,還是只是在請求生命週期的剩餘時間內被鎖定了? (實際使用该變數為nil,我很好奇)

最新回復
  • 5月前
    1 #

    是的,除非將其強製轉換迴陣列,否則它们只会被鎖定. PHP中有一些小" Gotchas",例如,在较早的版本中,您可以將常量定義為陣列,但是从不訪問其元素.即使是現在,您也可以將常量定義為資源(​​例如 define('MYSQL',mysql_connect()); ),尽管這会匯致無法預測的行為,並且應再次避免。

    通常,最好尽可能避免进行陣列到物件的轉換.如果確實需要執行此操作,請考虑建立一个新的 stdClass例項。 然後手動重命名所有變數,例如,重命名為 _0_1

    $a = array('cat','dog','pheasant');
    $o = new stdClass;
    foreach ($a as $k => $v) {
        if (is_numeric($k)) {
            $k = "_{$k}";
        }
        $o->$k = $v;
    }
    

    編輯:只是對该假設进行了另一項快速檢驗,是的,它们在物件上下文中正式"不存在"; 資料已儲存,但無法訪問,因此是最终的私有成員.這是測試:

    $a = array('one','two','three');
    $o = (object)$a;
    var_dump(property_exists($o, 1), property_exists($o, '1'));
    

    輸出為:

    bool(false)
    bool(false)
    

    再次編輯:有趣的旁註,以下操作返迴false:

    $a = array('one','two','three','banana' => 'lime');
    $b = array('one','two','banana' => 'lime');
    $y = (object)$a;
    $z = (object)$b;
    var_dump($y == $z);
    

  • 5月前
    2 #

    看来ArrayObject類可以訪問屬性

    $a = new ArrayObject($obj);
    echo $a[0];
    

  • 5月前
    3 #

    Yes, they are just locked away unless cast back to an array.

    也许這些屬性仍然存在並且可以訪問,只是不能直接訪問.但是,由於不確定源代碼中的內容,我不確定foreach在內部如何工作(可能会將物件轉換為陣列)。

    示例:

    $array = array('one', 'two', 'three', 'four');
    $obj = (object) $array;
    foreach ($obj as $key => &$val) {
        print "$key -> $val<br>";
        $val = 'Nhaca';
        var_dump($obj);
    }
    print_r($obj);
    print_r($array);
    

    輸出:

    0 -> one
    object(stdClass)[1]
      &string 'Nhaca' (length=5)
      string 'two' (length=3)
      string 'three' (length=5)
      string 'four' (length=4)
    1 -> two
    object(stdClass)[1]
      string 'Nhaca' (length=5)
      &string 'Nhaca' (length=5)
      string 'three' (length=5)
      string 'four' (length=4)
    2 -> three
    object(stdClass)[1]
      string 'Nhaca' (length=5)
      string 'Nhaca' (length=5)
      &string 'Nhaca' (length=5)
      string 'four' (length=4)
    3 -> four
    object(stdClass)[1]
      string 'Nhaca' (length=5)
      string 'Nhaca' (length=5)
      string 'Nhaca' (length=5)
      &string 'Nhaca' (length=5)
    stdClass Object ( [0] => Nhaca [1] => Nhaca [2] => Nhaca [3] => Nhaca ) 
    Array ( [0] => one [1] => two [2] => three [3] => four )
    

  • 5月前
    4 #

    我认為您会收到一條錯誤訊息,因為將陣列的整數键強製轉換為物件/子物件將破壞PHP變數的命名約定。

    提示:

      Decide before hands whether you want to have an OBJECTARRAY

      在进行型別轉換時要小心(例如(object)array(1 =>'string')不要這樣做)

      使用轉換进行驗證,而不进行轉換

      避免將物件用作"偽"陣列

  • r:為什麼在分組的datatable內部的lm上使用update会丢失其模型資料?
  • c++:如何使用OpenSSL的SHA256函式