1

ZendFramework 애플리케이션을위한 간단한 CMS 모듈을 구축하고 있습니다.ZF1 : 데이터베이스의 경로

현재 모든 경로가 .ini 파일에 있습니다. DB를 사용하도록 만들 수 있습니까? 또는 경로가 .ini 파일에 존재하지 않는 경우 대체 방법을 DB 검사에 구축 할 수 있습니다.

UPDATE - 솔루션

희망이 도움이 될 것입니다 누군가가 - 나는 정의 My_Db_table 내가 여기에 게시하지 않은 My_Db_Row 가지고 있습니다. 그래서 -> fetchAllActive() 아마 -> fetchAll() 변경해야합니다; 행 객체의 getter는 작동하지 않을 수도 있고 사용자 정의인지를 기억하지 못할 수도 있습니다 .-)

라우터는 기본적으로 다른 경로가 적용되지 않으면 DB를 검사하지만, ie .ini 파일에서. 이 방법이 모든 경로 유형에서 작동하는지 확인하지는 않았지만 기본 경로 유형과 함께 작동합니다. DB 경로를 사용하여 pageId와 같은 추가 매개 변수가있는 pageController를 route_defaults 셀에 JSON 문자열로 저장합니다. 하지만 기본적으로 모든 종류의 경로에 사용할 수 있습니다.

<?php 

class My_Controller_Router_Rewrite extends Zend_Controller_Router_Rewrite 
{ 


    /** 
    * Retrieve a named route 
    * 
    * @param string $name Name of the route 
    * @throws Zend_Controller_Router_Exception 
    * @return Zend_Controller_Router_Route_Interface Route object 
    */ 
    public function getRoute($name) 
    { 
     if (!isset($this->_routes[$name])) { 
      /* BEGIN - DB routes */ 
      $routes = new Routes(); 
      $route = $routes->getNamedRoute($name); 
      if($route instanceof Zend_Controller_Router_Route_Abstract) { 
       $this->addRoute($name, $route); 
      } 
      /* END - DB routes */ 
      if (!isset($this->_routes[$name])) { 
       require_once 'Zend/Controller/Router/Exception.php'; 
       throw new Zend_Controller_Router_Exception("Route $name is not defined"); 
      } 
     } 

     return $this->_routes[$name]; 
    } 


    /** 
    * Find a matching route to the current PATH_INFO and inject 
    * returning values to the Request object. 
    * 
    * @throws Zend_Controller_Router_Exception 
    * @return Zend_Controller_Request_Abstract Request object 
    */ 
    public function route(Zend_Controller_Request_Abstract $request) 
    { 
     if (!$request instanceof Zend_Controller_Request_Http) { 
      require_once 'Zend/Controller/Router/Exception.php'; 
      throw new Zend_Controller_Router_Exception('Zend_Controller_Router_Rewrite requires a Zend_Controller_Request_Http-based request object'); 
     } 

     if ($this->_useDefaultRoutes) { 
      $this->addDefaultRoutes(); 
     } 

     // Find the matching route 
     $routeMatched = false; 

     foreach (array_reverse($this->_routes, true) as $name => $route) { 
      // TODO: Should be an interface method. Hack for 1.0 BC 
      if (method_exists($route, 'isAbstract') && $route->isAbstract()) { 
       continue; 
      } 

      // TODO: Should be an interface method. Hack for 1.0 BC 
      if (!method_exists($route, 'getVersion') || $route->getVersion() == 1) { 
       $match = $request->getPathInfo(); 
      } else { 
       $match = $request; 
      } 

      if ($params = $route->match($match)) { 
       $this->_setRequestParams($request, $params); 
       $this->_currentRoute = $name; 
       $routeMatched  = true; 
       break; 
      } 
     } 

     /* BEGIN - DB routes */ 
     $front = Zend_Controller_Front::getInstance(); 

     if (!$routeMatched || ($routeMatched && !Zend_Controller_Front::getInstance()->getDispatcher()->isDispatchable($request))) { 
      $routes = new Routes(); 
      $dbRoutes = $routes->getRouterRoutes(); 

      foreach ($dbRoutes as $name => $route) { 
       // TODO: Should be an interface method. Hack for 1.0 BC 
       if (method_exists($route, 'isAbstract') && $route->isAbstract()) { 
        continue; 
       } 

       // TODO: Should be an interface method. Hack for 1.0 BC 
       if (!method_exists($route, 'getVersion') || $route->getVersion() == 1) { 
        $match = $request->getPathInfo(); 
       } else { 
        $match = $request; 
       } 

       if ($params = $route->match($match)) { 
        $this->_setRequestParams($request, $params); 
        $this->_currentRoute = $name; 
        $routeMatched  = true; 
        break; 
       } 
      } 
     } 
     /* END - DB routes */ 

     if(!$routeMatched) { 
      require_once 'Zend/Controller/Router/Exception.php'; 
      throw new Zend_Controller_Router_Exception('No route matched the request', 404); 
     } 

     if($this->_useCurrentParamsAsGlobal) { 
      $params = $request->getParams(); 
      foreach($params as $param => $value) { 
       $this->setGlobalParam($param, $value); 
      } 
     } 

     return $request; 

    } 

} 

경로 Db_Table 모델 내/컨트롤러/라우터/Rewrite.php

부트 스트랩

function _initApplication() 
{ 
    // Something taken out for simplicity 

    $this->bootstrap('frontcontroller'); 
    $front = $this->getResource('frontcontroller'); 

    $router = new My_Controller_Router_Rewrite(); 
    $front->setRouter($router); 

    // Something taken out for simplicity   
} 
에서

<?php 

class Routes extends My_Db_Table 
{ 
    protected $_name = 'routes'; 
    protected $_rowClass = 'Route'; 

    public static $primaryColumn = 'route_id'; 
    public static $statusColumn = 'route_status'; 
    public static $nameColumn = 'route_name'; 
    public static $typeColumn = 'route_type'; 
    public static $urlColumn = 'route_url'; 
    public static $moduleColumn = 'route_module'; 
    public static $controllerColumnn = 'route_controller'; 
    public static $actionColumnn = 'route_action'; 
    public static $defaultsColumnn = 'route_defaults'; 
    public static $reqsColumnn = 'route_reqs'; 
    public static $createdColumnn = 'route_created'; 

    public function getRouterRoutes() { 
     $routes = array(); 
     $rowset = $this->fetchAllActive(); 
     foreach($rowset as $row) { 
      $routes[$row->getName()] = $row->getRouteObject(); 
     } 
     return $routes;  
    } 

    public function getNamedRoute($name) { 
     $select = $this->select() 
         ->where(self::$statusColumn . ' = ?', 1) 
         ->where(self::$nameColumn . ' = ?', $name); 
     $rowset = $this->fetchAll($select); 
     foreach($rowset as $row) { 
      return $row->getRouteObject(); 
     } 
    } 
} 

경로 - 라우팅 테이블 Db_Table_row

<?php 

class Route extends My_Db_Table_Row_Observable 
{ 

    public function getType() { 
     if(empty($this->{Routes::$typeColumn})) { 
      return "Zend_Controller_Router_Route"; 
     } else { 
      return $this->{Routes::$typeColumn}; 
     } 
    } 

    public function getDefaults() { 
     $defaults = $this->{Routes::$defaultsColumnn}; 
     if($defaults) { 
      $defaults = Zend_Json::decode($defaults); 
     } else { 
      $defaults = array(); 
     } 

     $defaults['module'] = $this->getModule(); 
     $defaults['controller'] = $this->getController(); 
     $defaults['action'] = $this->getAction(); 

     return $defaults; 
    } 

    public function getReqs() { 
     $reqs = $this->{Routes::$reqsColumnn}; 
     if($reqs) { 
      $reqs = Zend_Json::decode($reqs); 
     } else { 
      $reqs = array(); 
     } 
     return $reqs; 
    } 

    public function getModule() { 
     if(empty($this->{Routes::$moduleColumn})) { 
      return "default"; 
     } else { 
      return $this->{Routes::$moduleColumn}; 
     } 
    } 
    public function getController() { 
     if(empty($this->{Routes::$controllerColumnn})) { 
      return "default"; 
     } else { 
      return $this->{Routes::$controllerColumnn}; 
     } 
    } 
    public function getAction() { 
     if(empty($this->{Routes::$actionColumnn})) { 
      return "default"; 
     } else { 
      return $this->{Routes::$actionColumnn}; 
     } 
    } 
    public function getRouteObject() { 
     $class = $this->getType(); 
     $defaults = $this->getDefaults(); 
     $reqs = $this->getReqs(); 
     $route = new $class($this->getUrl(), $defaults, $reqs); 
     return $route; 
    } 
} 

SQL 스키마 내가 생각할 수있는 세 가지 방법이 있습니다

CREATE TABLE IF NOT EXISTS `routes` (
    `route_id` smallint(1) unsigned NOT NULL AUTO_INCREMENT, 
    `route_status` tinyint(1) unsigned NOT NULL, 
    `route_name` varchar(16) NOT NULL, 
    `route_type` varchar(255) NOT NULL, 
    `route_url` varchar(255) NOT NULL, 
    `route_module` varchar(32) NOT NULL, 
    `route_controller` varchar(32) NOT NULL, 
    `route_action` varchar(32) NOT NULL, 
    `route_defaults` varchar(255) NOT NULL, 
    `route_reqs` varchar(255) NOT NULL, 
    `route_created` datetime NOT NULL, 
    PRIMARY KEY (`route_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; 
+0

이 기사가 도움이 될 수도 있습니다. http://richard.parnaby-king.co.uk/2013/04/zend-framework-routing-solutions/ – Flixer

답변

0

.

먼저 ZF1에서 성공적으로 사용했습니다. 라우팅 자체에 대해서는 Here's the code입니다. 아이디어는 간단합니다. "별칭"라우팅을 설정합니다 (내 경우에는 ".html"접미사를 사용하여 다른 URL과 구별됩니다). 라우팅이 발견되면 DB에서 별칭을 가져온 다음 대상 컨트롤러 + 작업의 요청을 DB (like here)에 정의 된 항목으로 전달할 수 있습니다. 내 코드가 예쁜 것은 아니지만 작동합니다.

둘째 : 자신의 라우터를 작성하십시오. 라우터 클래스를 확장하고 그곳에 라우트 해결 규칙을 추가하기 만하면됩니다. 즉, DB에서 데이터를 가져와 별칭이 데이터베이스에 있으면 true를 반환하고 params를 반환합니다.

세 번째 : 별칭 테이블을 긁어내어 .ini 파일 (또는 사용중인 모든 캐시)에 저장합니다. 이것은 이미 구현 한 것과 많이 다르지 않으므로 별칭 스크래핑을 자동화하는 것이 좋습니다.

+0

나는 Zend_Controler_Router_Rewrite를 확장하고 결국 route() 함수 로드 된 routes.ini의 디스패치 가능 루트에서 요청이 다시 일치하지 않으면 DB에 대해 확인하십시오.부트 스트랩의 응용 프로그램에 내 맞춤 My_Controller_Router_Rewrite 클래스를 사용하는 데 필요한 다른 변경 사항은 :-) – Phliplip

+0

나는 이것이 "올바른"방법이라고 생각합니다. – mingos

+0

OP에 내 솔루션을 추가했습니다. – Phliplip

관련 문제