2012-01-18 40 views
10

我正在創建一個網站,並將在以後創建一個移動應用程序。Zend Framework - 如何創建可在外部和內部訪問的API?

我希望能夠提供數據的相同水平(即書籍的列表),到網站和應用程序都。我想爲此使用API​​,但我正努力在網上找到任何示例或體面的文章。所以我想我的問題是,如果我要通過HTTP創建一個移動應用程序可訪問的JSON'端點'(例如http://www.mysite.com/api/v1.0/json),我的Zend應用程序如何從內部訪問相同的功能?

(很明顯,我不想複製數據庫的交互「模式」的步驟)

+0

那你最終會使用嗎?我現在處於類似的情況。 – 2012-10-12 18:04:07

回答

4

從Zend是真的不平安,不幸的是,你最好的選擇是JSON-RPC。

你可以做一個控制器,或者你可以讓另外一個ajax.php你的index.php減少這樣的傢伙開銷確實here

基本上,所有你需要做的是這樣的:

$server = new Zend_Json_Server(); 
$server->setClass('My_Class_With_Public_Methods'); 
// I've found that a lot of clients only support 2.0 
$server->getRequest()->setVersion("2.0"); 
if ('GET' == $_SERVER['REQUEST_METHOD']) { 
    // Indicate the URL endpoint, and the JSON-RPC version used: 
    $server->setTarget('/ajax.php') 
      ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2); 

    // Grab the SMD 
    $smd = $server->getServiceMap(); 

    // Return the SMD to the client 
    header('Content-Type: application/json'); 
    echo $smd; 
    return; 
} 

$server->handle(); 

然後在某個地方佈局:

$server = new Zend_Json_Server(); 
$server->setClass('My_Class_With_Public_Methods'); 
$smd = $server->getServiceMap(); 
?> 
<script> 
$(document).ready(function() { 
    rpc = jQuery.Zend.jsonrpc({ 
     url : <?=json_encode($this->baseUrl('/ajax'))?> 
     , smd : <?=$smd?> 
     , async : true 
    }); 
}); 
</script> 

例如起見,下面是該類:

class My_Class_With_Public_Methods { 
    /** 
     * Be sure to properly phpdoc your methods, 
     * the rpc clients like it when you do 
     * 
     * @param float $param1 
     * @param float $param2 
     * @return float 
     */ 
    public function someMethodInThatClass ($param1, $param2) { 
     return $param1 + $param2; 
    } 
} 

,那麼你可以簡單的調用方法,像這樣在javascript:

rpc.someMethodInThatClass(first_param, second_param, { 
    // if async = true when you setup rpc, 
    // then the last param is an object w/ callbacks 
    'success' : function(data) { 

    } 
    'error' : function(data) { 

    } 
}); 

不會有很多衆所周知的JSON-RPC庫爲Android/iPhone - 但我發現這一點也適用Zend_Json_Server爲Android:

http://software.dzhuvinov.com/json-rpc-2.0-base.html

,這適用於iPhone:

http://www.dizzey.com/development/ios/calling-json-rpc-webservice-in-ios/

從這裏,很明顯,你可以以同樣的方式,使用Javascript /您的移動應用程序確實使用My_Class_With_Public_Methods。

+0

如何從「書籍」控制器的「索引」操作中調用someMethodInThatClass方法 - 例如? – Sjwdavies 2012-01-19 14:40:33

+1

呵呵,通過它來呼叫? '$ myobj = new My_Class_With_Public_Methods(); $ myobj-> someMethodInThatClass();' – 2012-01-19 15:09:40

+0

謝謝史蒂芬 - 這不會最終與'脂肪控制器',但例如, 'My_Class_With_Public_Methods'可能很龐大?我想我需要通過這個控制器將每個內部請求指向數據庫以獲取數據?還是以正常方式引導這些數據,然後通過編寫「My_Class_With_Public_Methods」文件並選擇我想要公開提供的數據庫交互來「開放」數據檢索過程? – Sjwdavies 2012-01-19 15:16:48

1

從我的角度來看,這是一個與架構相關的問題,而不是Zend Framework問題。

您正在查找的是面向服務的體系結構(Service-Oriented Architecture,SOA)。

SOA背後的前提很簡單,建立一個單一的API,並擁有一切通過它,無論在內部,還是外部的。亞馬遜是SOA的熱門支持者。

在實踐中,這意味着你暴露你的API完全按照自己的內部使用它。在OOP中,這意味着無論何時從外部源調用API(例如:REST API),都將指定類名稱,方法名稱和參數列表,並且您將收到一個對象作爲回報,就像你在內部調用它一樣。

每例如,你有這些:

class HelloInstance { 
    public $hello; 
    public function __construct($hello) { $this->hello = $hello; } 
} 

class Hello { 
    public function getHello() { return new HelloInstance('world'); } 
} 

class FooInstance { 
    public $foo; 
    public function __construct($foo) { $this->foo = $foo; } 
} 

class Foo { 
    public function getFoo($value) { return new FooInstance($value); } 
} 

如果你想在內部使用它們,你會怎麼做:

$hello = new Hello; 
$helloInst = $hello->getHello(); 

$foo = new Foo; 
$fooInst = $foo->getFoo('bar'); 

現在,你只需要一個通往外部公開這個API。這裏是一個非常簡單的例子:

include_once 'my_classes.php'; 

$class = $_GET['class']; 
$method = $_GET['method']; 

$obj = new $class; 
$return = $obj->$method(isset($_GET['value']) ? $_GET['value'] : null); 

header('Content-Type: application/json'); 
echo json_encode($return); 

你可以做同樣的兩個電話我之前表現出來,並得到相同的結果,使用REST調用:

http://my_server/my_gateway.php?class=Hello&method=getHello 
http://my_server/my_gateway.php?class=Foo&method=getFoo&value=bar 
+1

這是一個很好的建築答案立場,但是1.您所描述的REST並不是真正的RESTful,它更類似於SOAP。 SOAP是一切都很好,但它絕對不是* RESTful,2。Zend內置了SOA - 它的REST服務器是廢話,不是RESTful,但它的JSON/XML RPC功能正確。當然,你的方法很好 - 但它沒有利用任何Zend的內部SOA。我想這不一定是壞事,但只是想我會指出來。 – 2012-01-18 20:42:15

+0

只是好奇,它不是RESTful? – drew010 2012-01-18 23:03:39

+0

@ StephenJ.Fuhry:僅僅因爲你做了遠程過程調用並不意味着它不能成爲RESTful。哦,我從來沒有說過,以上是RESTful的方式。這根本不像SOAP。 – netcoder 2012-01-19 14:11:43