[PHP] Jsnao 繼承 ArrayObject 更方便的陣列轉物件寫法

前言

主旨是 把陣列的寫法,改為使用物件的寫法風格,而且隨時還可以使用陣列的風格使用。例如

$user['phone'] = "0933-333-333"; // 指定使用者的電話是 0933-333-333

改用這種寫法來取代:

$user->phone = "0933-333-333";
echo $user['phone']; // 輸出 0933-333-333
echo $user->phone; // 仍然輸出 0933-333-333

或是交換寫…..

$user['phone'] = "0933-333-333";
echo $user->phone; // 輸出 0933-333-333
echo $user['phone']; // 仍然輸出 0933-333-333

我們打這些符號 [”] 會比箭頭符號 -> 要來的手指頭不靈活--而且大量程式碼擠在一起時畫面很髒。所以我希望透過改寫風格,讓程式碼更乾淨、手指頭負擔更小、開發速度更快。

其實之前前幾篇有提到 PHP 的 ArrayObject 原生功能(是的,原生 PHP 有支持只是用的人太少,功能兩光兩光),但因為遇到多維陣列時,想要遞迴到底層把它轉換成物件,就會遇到一些狀況,例如:

$array['a1']             = "value1"; 
$array['a2']['b1']       = "value2"; 
$array['a2']['b2']['c1'] = "value3"; 
$array['a2']['b2']['c2'] = "value4";
$test                    = new ArrayObject($array);

echo $test->offsetGet('a1') . "<br>"; //顯示 value1

//只能輸出到這(因為型態是陣列不是物件),因此無法使用這種寫法 offsetGet()->offsetGet()->....
echo $test->offsetGet('a2'); // 注意,會顯示 Array
所以,如果要使用
$test->a2->b2->c2

來取代陣列寫法

$test['a2']['b2']['c2']

那就只能先建立 ArrayObject 並指派空的陣列容器 ,再用 ArrayObject 的特性來賦值進去。可是這樣一來,會沒辦法轉換『原本已存在的陣列』,因為在建構子的時候一定要指派空陣列。

$a = new ArrayObject(array(), ArrayObject::STD_PROP_LIST); //建構子的地方,要先放入一個空陣列,轉換成 ArrayObject 型態
$a->first = "001"; //這裡以下才能使用物件風格操作
$a->second->one = "002";
$a->second->two = "003";
echo $a->second->one; // 顯示 002
後來找了很久,台灣網友的資料很少,有也只是考慮到 (object)$array 這種考慮不周的,幸好看到對岸網友有自行編撰且幾乎符合我要的方法。於是我改寫過發佈在 GitHub:https://github.com/fdjkgh580/jsnao,現在也可以使用 composer 下載喔!

 

我為什麼要使用呢?

加速!時間就是錢,錢就是我的生活。一天八小時可以幫我省下好幾分鐘,尤其是當我文思泉湧的開發程式的時候,或是突然想到什麼點子要馬上打出來測試時,打程式的速度才跟得上我的思考。像這時候我就會覺得打陣列超級麻煩,跟不上我思考的速度。當然最重要的是,我想偷懶--誰想那麼認真呢?懶,可是工程師的美德呀!說回來我們來體會一下。

例如,我們開發購物車流程好了。試著敲一下鍵盤,感覺一下你打字的速度跟手感

echo $user['David']['orderlist'][0]['amount']; // 呼叫使用者叫做 David 的第一筆訂單總金額

跟打這段

echo $user->David->orderlist[0]->amount;

哪個又快手指又舒服呢?我們再試試

$user['cart']['product']['price'] = 120; // 設定某個使用者購物車中的某商品價格是120元

跟打這段

$user->cart->product->price = 120;

是不是省時間,手指頭又不會打結呢?

接著,有時候在除錯時,我們想要看整體結構。例如,我們想要看 $user 這個物件的所有元素。以往我們用 print_r() 之類的方法,現在我們直接 echo 就好。

$data['status'] = "success";
$data['message'] = "登入成功";
$data = new jsnao($data);
echo $data; // Debug 就這樣檢視所有元素,方便吧,手指頭又舒服多了

如果開發 API 遠端回傳的是 json 格式,一樣直接使用

$mix = '{"my":"Jsnao"}';
$result = new Jsnao($mix);
$result->my; // 輸出: Jsnao
$result['my']; // 仍然輸出 Jsnao

Composer 下載方式

建立 composer.json

{  
    "require": {  
        "jsnlib/jsnao": "dev-master"
    }  
}

使用 composer 指令

composer install

下載完畢以後,就可以在你的文件這麼自動載入 Jsnao。

<?
require __DIR__ . '/vendor/autoload.php';

$mix = array('my'=>"Jsnao");
$ary = new Jsnao($mix);
echo $ary;

這支 Jsnao 的用法就這麼方便了。

include_once("../jsnao.php");

// 如果鍵不是以數字為開頭,就使用這種普通方法。
$cart = array
(
    'A001'   =>  array
    (
        'name'  =>  'apple',
    )
);
$cart = new jsnao($cart);

// 取值
$cart->A001->name; //output: apple

// 賦值
$cart->A002 = array('name' => 'banana');
//或
$cart->A002 = array();
$cart->A002->name = 'banana';

// 修改
$cart->A001->name = 'cherry';

// 刪除
$cart->A003 = array('name' => 'bag');
unset($cart->A003);

echo $cart;

傳統下載

點我 馬上從GitHub下載,或是先去 我的GitHub 看看。

php – 利用 stdClass 取代陣列

[php]
<?

//這樣就可以直接替換掉陣列, 改用物件來操作了

$ary[‘a’] = ‘test’;
$ary[‘apple’][‘color’] = ‘red’;
$ary[‘apple’][‘size’] = ‘m’;
$ary[‘else’] = ‘HELLOW’;

function change($ary){
foreach ($ary as $key => $val) {
if (is_array($ary[$key])) {
$new->$key = new stdClass();
$new->$key = change($val);
}
else $new->$key = $val;
}
return $new;
}
$new = change($ary);

/*
若要將$new->a改成$new->a->b = "test"; 需要事先unset(),否則會錯誤!
而且可以直接指定下去,不需要逐一宣告new stdClass(), 例如
unset($new->a);
$new->a->b->c->d->e->f->g = "HELLOW";
*/
print_r($new);

?>
[/php]

[PHP] ArrayObject 陣列轉成物件

PHP 的類別『 ArrayObject 』
可以讓你控制陣列的方式改成物件的方式喔!
這樣你的版面會清爽許多 ~

例如我們一般輸出陣列的方法:ehco $array[‘first’];
是不是出現 [ ‘ ‘ ]
看起來很雜?
轉成物件以後,只需要用箭頭不是快多了?
打字速度雖然只差個幾毫秒,可是一旦量多了以後,編輯起來的速度也有影響唷!

重點是版面只會看到 ->
不會看到一堆的 [] ‘ ‘ 符號喔

[php]
$csss = new ArrayObject(array(), ArrayObject::STD_PROP_LIST);
$csss->first->a = "1";
$csss->first->b = "2";
$csss->first->c = "3";

foreach ($csss->first as $key => $val) {
echo $val . "";
}
[/php]

若有已存在的物件也可以這樣
利用append()追加元素

[php]
$csss = array("A","B","C");
$csss = new ArrayObject($csss);
$csss->append(array("D"));
print_r($csss);
[/php]

如果陣列的鍵是數字,會遇到一個問題:
$csss[0] = “星”;
$csss[1] = “期”;
$csss = new ArrayObject($csss);
要怎麼用物件的方式輸出 「星」呢?
我們都知道,物件裡是不能用數字,
所已不能使用$csss->0 這個方法!
這時候要使用offsetGet()來找出囉~

[php]
$csss[0] = "星";
$csss[1] = "期";
$csss = new ArrayObject($csss);
echo $csss->offsetGet(0); //輸出 星
[/php]

[PHP] 物件轉換陣列 – 巧用json_decode的方法

[php]

<?php

$a = new ArrayObject(array(), ArrayObject::STD_PROP_LIST);
$a->first = "001";
$a->second->one = "002";
$a->second->two = "003";

/*
* 若要將 物件 轉換為 陣列, 看了一下網路的寫法似乎都沒有官方的做法。
* 突然想到若用json_encode與json_decode就能簡易的轉換!
* 速度沒測過,不知道效能囉
*/

$json = json_encode($a);
$json = json_decode($json, true);
echo $json[‘second’][‘two’]; //得到003

?>

[/php]

[PHP] ArrayObject 用法 – 把物件當陣列用

[php]
<?
/*
* 使用 ArrayObject(array(), ArrayObject::STD_PROP_LIST);
* 把物件當陣列使用
*/
$a = new ArrayObject(array(), ArrayObject::STD_PROP_LIST);
$a->first = "001";
$a->second->one = "002";
$a->second->two = "003";

echo $a->first;

?>
[/php]