ssa/core

该软件包已被弃用且不再维护。未建议替代软件包。
该软件包最新版本(1.0.4)没有提供许可证信息。

一个将PHP服务简单地调用到JavaScript代码中的PHP软件包。

1.0.4 2015-04-30 15:03 UTC

This package is not auto-updated.

Last update: 2022-08-03 03:25:54 UTC


README

SSA是一个用于简单地执行Ajax调用的框架。您可以将服务作为PHP调用到JavaScript中。

使用方法

示例

SSA的使用非常简单,您创建自己的PHP服务,然后可以在JavaScript代码中调用此服务。例如:HelloWorld.php

namespace services\;

/**
 * simple example service
 *
 * @author deblock
 */
class HelloWorld {
    
    /**
     * return Hello <yourName> !!
     * @param string $yourName
     * @return string 
     */
    public function helloYou($yourName) {
        return 'Hello ' . $yourName.' !!';
    }
}

example.html

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <!-- include ssa core javascript -->
        <script type="text/javascript" src="javascript/ssa.js" ></script>
        <!-- include the autogenerate javascript service -->
        <script type="text/javascript" src="javascript.php?service=HelloWorld"></script>
        <script type="text/javascript">
            HelloWorld.helloYou('deblockt').done(function(result){
                document.getElementById('serviceResult').innerHTML = result;
            });
        </script>
    </head>
    <body>
        <div> SSA exemple </div>
        <div id="serviceResult"></div>
    </body>
</html>

此示例将"Hello deblock !!"添加到serviceResult div中。

工作原理

为了将服务转换为JavaScript服务,SSA使用文档注释。它使用@param注释来识别参数和类型参数。如果PHP参数没有注释,它们将不会被导出到JavaScript服务中。

为了运行服务,使用@param注释,类型用于将$_POST参数转换为PHP类型。类型支持可以是原始类型、完整类名(带有命名空间)、\DateTime(输入格式、文件或数组。\DateTime和数组是特定的。\DateTime类型有输入格式参数。例如:\DateTime(m/d/Y),数组可以有参数。例如:array(int) array(int) array(\Path\To\My\Class) array(file) ...

JavaScript服务有多个方法来处理Ajax事件。

  • fail:如果发生网络错误
  • always:在Ajax调用后立即运行
  • phpError:如果发生PHP错误则运行。(如果SSA模式为调试,则记录PHP错误)
  • done:当服务调用成功时运行。

ssa.js有两个默认处理程序

  • defaultFailHandler:如果没有指定特定处理程序,则使用默认处理程序。它可以由失败处理程序覆盖。
  • defaultPhpErrorHandler:如果没有指定特定处理程序,则使用默认处理程序。它可以由phpError处理程序覆盖。
  • addStartCallListener:在每次Ajax调用之前调用监听器
  • addEndCallListener:在每次Ajax调用之后调用监听器

serviceTest.js

myService.myAction('firstParameter', {attr1 : 'value1'})
         .done(function(returnValue, xhr) { alert(returnValue);})
         .fail(function(xhr) {alter('a network error occurs');})
         .phpError(function(errorPhp, xhr) {alert('an error occurs'.errorPhp.message);})
         .always(function(xhr){console.log('fin de la requête')}); 

每个回调都具有相同的作用域对象,您可以在这些回调之间传递变量。

支持

Ssa支持多种类型参数和返回值。参数和返回值可以是原始类型、对象或DateTime、数组,您可以直接添加其他类型支持。

Ssa支持文件上传,如果您想上传文件,则必须使用file或array(file)类型。

service.php

class FileService {

    /**
     * @param file $file
     */
    public function upload($file) {
        // file is like this
        // array(
        //  'name' => 'string',
        //  'size' => int,
        //  'error' => int,
        //  'tmp_name' => 'string',
        //  'type' => 'string'
        // )
    }
    
    /**
     * @param array(file) $files
     */
    public function uploadMultiple($files) {
        foreach ($files as $file) {
            $this->upload($file);
        }
    }
}

FileUpload.js

// upload one file
FileService.upload(document.getElementById('simpleFileUploadInput').files);
// upload multiple file
FileService.uploadMultipleFile(document.getElementById('multipleFileUploadInput').files);

警告:不是所有浏览器都支持上传文件,它使用FormData类。如果浏览器不支持此功能,则回调函数formDataError将被调用。当运行带有文件上传的服务时,如果此功能不受支持,则调用formDataError回调。

FileService.upload(document.getElementById('simpleFileUploadInput').files)
           .formDataError(function(){
                alert('Your navigator is too old for this function');
           });

Ssa支持多种JavaScript框架

  • 您可以在仅包含ssa.js文件的情况下使用ssa独立使用
  • 您可以使用ssa与angular js配合使用,只需包含ssa.js文件和您的服务生成文件。使用注入依赖关系来获取您的服务。例如:
  // add ssa as module dependencies
  var controller = angular.module('ssa.test', ['ssa']);
  // get simply your service on your controller with the service name. here the service is helloWorldService
  controller.controller('controller', function($scope, helloWorldService){   
  });
  • 您可以使用ssa与requirejs配合使用,只需在requirejs的配置中包含ssa。
// configuration must containe a ssa link
require.config({
  paths: {
      // you must add ssa srcipt on your configuration
      "ssa": "path/to/ssa/javascript/file",
      // warning if you don't use htaccess service param is like this /serviceName
      // if you use htacess you can have url like this /javascript/ssa/service/servicename.js who redirect on javascript.php
      // path of your javscript service generator
      "ssaService" : "javascript.php?type=requirejs&service=" 
  }
});

// juste require your service
require( ["ssaService/helloWorldService"],
  function(helloWorldService) {
    // helloWorldService is you php service
  }
);

如果您想查看SSA示例,可以查看test/ssa/toEndTest目录

配置

独立版本和Symfony版本之间的ssa配置不同。

Symfony版本

对于Symfony版本,您可以查看这个bundle项目

独立版本

独立版本的文档在下面。

注册您的服务

注册您的服务的一个简单方法是创建一个configuration.php文件。这个文件调用serviceManager来注册您自己的服务。

configuration.php

include 'autoload.php';

use ssa\ServiceManager;

// the first way to do this is with registerAllServices method 
ServiceManager::getInstance()->registerAllServices(array(
    // the first service is the class ssa\test\Service1 and we expose all this method 
    'service1' => array(
      'class' => 'ssa\test\Service1'
    ),
    // the second service is the class ssa\test\Service2 and we expose only the action1 and action2 method 
    'service2' => array(
      'class' => 'ssa\test\Service2',
      'methods' => array('action1','action2')
    )
));

// the second way to do this is the registerService function, you can only register one service
ServiceManager::getInstance()->registerService('service3','ssa\test\Service3');
// or
ServiceManager::getInstance()->registerService('service4','ssa\test\Service4', array('action1'));
  

配置SSA

SSA可以配置,配置可以在configuration.php文件中。

configuration.php

include 'autoload.php';

use ssa\Configuration;

Configuration::getInstance()->configure(array(
    'debug' => true, // if debug is true the generated javascript file are not minimized
    'cacheMode' => 'file', // if the cache is configured this cache mode is use, this can be file,apc,memcache,no(default)
    'cacheDirectory' => '', // if the cacheMode is file, this parameter is mandatory, this is the directory where the cache is put
    'memcacheHost' => '', // if the cacheMode is memcache is set this parameter is mandatory
    'memcachePort' => ''// if the cacheMode is memcache is set this parameter is mandatory
));

// the configuration can be do like this, example
Configuration::getInstance()->setDebug(true);
Configuration::getInstance()->setCacheMode('file');

/** service register **/

添加类型支持

如果ssa的默认类型支持不足以满足需求,您可以定义自己的类型支持。您有两种方式来实现,添加简单的类型支持(用于对象或参数),或者创建一个新的ParameterResolver来解析原始类型和对象。存在一个默认的ParameterResolver,它可以解析原始类型、数组、对象和\DateTime。

添加类型解析器的第一种方法是将它直接添加到默认的类型解析器中。configuration.php

/** register services, and configure ssa */

use ssa\runner\resolver\impl\DefaultParameterResolver;
$defaultParameter = DefaultParameterResolver::createDefaultParameterResolver();
$defaultParameter->addObjectResolver(new MyObjectResolver());
$defaultParameter->addPrimitiveResolver(new MyPrimitiveResolver());

您的ObjectResolver和ParameterResolver需要实现ssa\runner\resolver\ObjectResolver,ssa\runner\resolver\PrimitiveResolver。请参阅PrimitiveResolver和ObjectResolver的文档。

或者您可以创建自己的ParameterResolver(不推荐)。您的ParameterResolver需要实现ssa\runner\resolver\ParameterResolver。

run.php

include 'configuration.php';

use ssa\runner\ServiceRunner;
// get the service and the action : HelloWorld.sayHello
list($service, $action) = explode('.', $_GET['service']);

// create the service runner
$serviceRunner = new ServiceRunner($service, new MyParameterResolver());
// run the action with get parameters
echo $serviceRunner->runAction($action, $_GET);

创建一个编码器

编码器用于将函数返回值编码成JavaScript值。默认编码器是JsonEncoder,这个编码器可以转换原始类型、数组和对象。对象通过getter方法转换,每个getter转换成一个JSON属性。如果您需要,您可以创建自己的编码器,这很简单。在您的服务操作中,您需要添加@Encoder注解。Service.php

class Service {
  /**
   * @Encoder(\MyEncoder)
   *
   * @param string $firstParameter
   *
   * @return string
   */
  public function action($firstParameter) {
    return $firstParameter;
  }
}

操作方法使用MyEncoder将返回值转换为JSON或其他格式。您的编码器必须实现ssa\runner\converter\Encoder或扩展ssa\runner\converter\DefaultJsonEncoder。

安装

如果您想使用SSA,您有多种解决方案。

与Symfony一起使用

其他项目允许将此项目简单地添加到您的Symfony项目中。请参阅ssa/symfony。

使用独立版本

独立版本已启用。

使用Composer下载

第一种解决方案是使用一个使用composer的项目,您只需添加ssa/core依赖项。

不使用Composer下载

如果您不想使用composer,您可以将ssa添加到您的项目中。

  • 下载项目
  • 将项目添加到您的项目中
  • 更新您的自动加载器以自动加载ssa类。
  function __autoload($className)  {
    if (strpos($className, 'ssa\') == 0) {
      $file = str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
      include $YOUR_INSTALATION_DIRECTORY.DIRECTORY_SEPARATOR.$file;
    }
  }
  • 安装doctrine/annotations和doctrine/cache
  • 您现在可以使用SSA了

创建控制器

要使用SSA的独立版本,您需要使用两个PHP文件,一个用于创建JavaScript服务,另一个用于运行PHP控制器。这两个PHP文件需要使用配置PHP文件来注册您的服务。

configuration.php

include 'autoload.php';

use ssa\ServiceManager;
use ssa\Configuration;

// configure the ssa framework
Configuration::getInstance()->configure(array(
    'debug' => true
));
// registrer your services
ServiceManager::getInstance()->registerAllServices(array(
    'HelloWorld' => array('class' => 'ssa\toEndTest\HelloWorld')
));

run.php

include 'configuration.php';

use ssa\runner\ServiceRunner;
// get the service and the action : HelloWorld.sayHello
list($service, $action) = explode('.', $_GET['service']);

// create the service runner
$serviceRunner = new ServiceRunner($service);
// run the action with get parameters
echo $serviceRunner->runAction($action, array_merge($_POST, $_FILES));

javascript.php

include 'configuration.php';

use ssa\converter\JavascriptConverter;
use ssa\converter\SimpleUrlFactory;

// url use to call php services
$url = substr($_SERVER['REQUEST_URI'],0, strrpos($_SERVER['REQUEST_URI'], '/'));
// url factory use for create the service run url (your run.php file)
$factory = new SimpleUrlFactory("http://$_SERVER[HTTP_HOST]$url/run.php?service={action}&test=true");
// create the converter convert the service into Javascript service, service use $_GET parameter
$converter = new JavascriptConverter($_GET['service'], $factory);

echo $converter->convert();

例如,要获取JavaScript HelloWorld服务,URL是:https:///javascript.php?service=HelloWorld

最后,您需要将ssa.js包含到您的JavaScript文件夹中。

更多用法

在生成的服务上添加自定义JavaScript

您可以在生成的服务上添加自己的JavaScript。如果您想注入自己的代码,您需要使用ssa\converter\annotations\AddJavascript注解。它有自己的参数:要添加的JS文件,路径是相对路径。

AuthenticateService.php

use ssa\converter\annotations\AddJavascript;
/**
* @AddJavascript("../../javascript/ssaSecureModule.js")
* @author thomas
*/	
class AuthenticateService {
}

如果您想在生成的服务上添加方法,您可以创建一个名为"module"的函数,这个函数有一个参数:生成的服务。这个函数在服务生成时被调用。

添加serviceRunner处理器

您可以为serviceRunner添加处理器,处理器在服务运行前后被调用。处理器是一个注解,如果注解在函数注释上,处理器将被调用。

您需要创建一个这样的注解

Secure.php

use ssa\runner\annotations\RunnerHandler;
use Doctrine\Common\Annotations\Annotation;


/**
*
* @Annotation
* 
* @author thomas
*/
class Secure implements RunnerHandler {
   /**
    * set state magic method for cache method
    * @param type $array
    * @return \ssa\secure\annotations\Secure
    */
   public static function __set_state($array) {
       $secure = new Secure();
       return $secure;
   }
   
   /**
    * call before service call
    *
    * @param string $method the action name
    * @param array $inputParameters service parameter, (service => the service call, service.method)
    * @param ServiceMetadata $metaData
    *
    * @throw Exception if action must no be call
    */
   public function before($method,array &$inputParameters,ServiceMetadata $metaData) {
   
   }
   
   /**
    * call before service call
    *
    * @param string $method the action name
    * @param array $inputParameters service parameter, (service => the service call, service.method)
    * @param mixed the service result before encoding
    * @param ServiceMetadata $metaData
    *
    * can return value tranformed $result, encoder is call after this method
    */
   public function after($method,array &$inputParameters, $result, ServiceMetadata $metaData) {
   	
   }

}

您可以这样调用您的处理器

service.php

   /**
    * @Secure
    *
    * @param string $yourName
    * @return string 
    */
   public function helloYou($userId) {
       return 'hello ' .$userId.'!!!';
   }