Zend Framework - 如何创建可在外部和内部访问的API?

时间:2012-01-18 18:22:22

标签: zend-framework

我希望创建一个网站,并将在以后创建一个移动应用程序。

我希望能够为网站和应用提供相同级别的数据(即图书清单)。我想为此使用API​​,但我很难在网上找到任何示例或体面的文章。

所以我想我的问题是,如果我要通过HTTP创建一个移动应用程序可访问的JSON'端点'(例如http://www.mysite.com/api/v1.0/json),如何从我的Zend应用程序内部访问相同的功能?

(显然我不想复制数据库交互'模型'步骤)

2 个答案:

答案 0 :(得分:4)

由于Zend真的不是RESTful,不幸的是,你最好的选择是JSON-Rpc。

你可以在一个控制器中完成它,或者除了index.php之外你还可以创建一个ajax.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) {

    }
});

Android / iPhone上没有很多着名的JSON-rpc库 - 但我发现这适用于Android的Zend_Json_Server:

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。

答案 1 :(得分:1)

从我的观点来看,这更像是一个与架构相关的问题而不是Zend Framework问题。

您正在寻找的是面向服务的体系结构(SOA)。

SOA背后的前提很简单,构建一个单独的API,无论是内部还是外部,都可以通过它。 SOA的流行支持者是亚马逊。

实际上,这意味着您完全按照内部使用API​​公开API。在OOP中,这意味着无论何时从外部源(例如:REST API)调用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