2012-11-10 2 views
3

저는 Zend Framework 2를 처음 접해서이 프레임 워크를 배우고 싶습니다. 라우터에서 URL 별칭을 만들고 싶습니다. 난 내 응용 프로그램의 기본 컨트롤러의 기본 액션에 www.myapp.local/node/1 그 경로를 입력 할 때 예를 들어 , 나는 ZF2 : 라우터에서 URL 별명을 생성하십시오.

'router' => array(
    'routes' => array(

     'home' => array(
      'type' => 'Zend\Mvc\Router\Http\Literal', 
      'options' => array(
       'route' => '/', 
       'defaults' => array(
        'controller' => 'Application\Controller\Index', 
        'action'  => 'index', 
       ), 
      ), 
     ), 
     'node' => array(
      'type' => 'Application\Controller\AliasSegment', 
      'options' => array(
       'route' => '/node[/:id]', 
       'constraints' => array(
        'id' => '[0-9]+' 
       ), 
       'defaults' => array(
        '__NAMESPACE__' => 'Application\Controller', 
        'controller' => 'Index', 
        'action'  => 'index', 
        'id'   => '0' 
       ), 
      ), 
      'may_terminate' => true, 
     ), 

    ), 
), 

module.config.php

이 뭔가를 정의했습니다. 내가 원하는 것은 URL 경로에 대한 별칭을 처리 할 수있는 라우터 확장입니다. 예 :

www.myapp.local/node/1 = www.myapp.local/aboutus 
www.myapp.local/node/2 = www.myapp.local/company/gallery 

ZF에서 가능하다는 것을 알고 있습니다. 다음 링크는 ZF에서이를 달성하는 방법을 개별지도하는 것입니다 friendly urls 을 나는이 폴란드어 것을 알고 있지만, 코드가 자명 내가 생각입니다 :)

아이디어는 조립 유효한 URL 별칭을 사용하는 URL 도우미를 사용하는 것입니다 또는 일반 세그먼트 (노드/[: ID])

이미 내 응용 프로그램 \ 컨트롤러 폴더에 AliasSegment 클래스를 만든하지만 나에게 오류 보여줍니다 (불완전)

Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Application\Controller\AliasSegment' in C:\xampp\htdocs\industengine\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:450 Stack trace: #0 

내 AliasSegment 클래스 :

<?php 

    namespace Zend\Mvc\Router\Http; 

    use Traversable; 
    use Zend\Mvc\Router\Exception; 
    use Zend\Stdlib\ArrayUtils; 
    use Zend\Stdlib\RequestInterface as Request; 

class AliasSegment extends Segment 
{ 


    public function match(Request $request, $pathOffset = null) 
    { 


    } 

} 

나는 몇 시간 동안 대답을 찾고 있었고 아무것도 찾을 수 없었다. 적어도 제가 잘못하고있는 부분, 코드를 삽입 할 곳 또는 어쩌면 당신은 더 나은 해결책을 알고 있습니까?

나는 준비된 응용 프로그램을 찾고 있지 않습니다. 내가 뭔가를 배우고 싶어하지만 당신은 세부 사항을 편집 제 영어 :

미리 미안에

감사합니다 :) 나에게 답을 말할 수 있다면 감사하겠습니다 :

내 사용자 지정 라우터가 지금 일하고있어. 이 시점에서 별칭은 하드 코드되지만 작동합니다.

내 AliasSegment 클래스는 지금 보이는이 경우 /about/gallery에서

<?php 

namespace Application\Controller; 

use Traversable; 
use Zend\Mvc\Router\Exception; 
use Zend\Stdlib\ArrayUtils; 
use Zend\Stdlib\RequestInterface as Request; 
use Zend\Mvc\Router\Http; 

class AliasSegment extends \Zend\Mvc\Router\Http\Segment 
{ 


    public function match(Request $request, $pathOffset = null) 
    { 
     $uri = $request->getUri(); 
     $path = $uri->getPath(); 

     //sample logic here 
     //for /about/gallery uri set node id to 1 
     //todo: get action, controller and module from navigation   
     if($path == '/about/gallery'){ 
      $uri->setPath('/node/1'); 
      $request->setUri($uri); 
     } 

     return parent::match($request, $pathOffset); 

    } 

    protected function buildPath(array $parts, array $mergedParams, $isOptional, $hasChild) 
    { 

     if(isset($mergedParams['link'])){ 
      return $mergedParams['link']; 
     } 

     return parent::buildPath($parts, $mergedParams, $isOptional, $hasChild); 
    } 

} 

/node/1에 대한 별칭입니다. 두 주소 모두 정확합니다. buildPath 함수는 별칭 경로를 올바르게 반환합니다. 글쎄,이 사람이 유용 할 희망 :

그러나 나는 '링크'라는 추가 매개 변수로 Zend_Navigation에서 설정하고 싶습니다.

나는 달성하고자하는 것의 50 %를했지만 지금 라우터에서 Zend_Navigation을 얻는 데 문제가 있습니다. 나는 그것을 어떻게 통과해야할지 모른다. 나는 다음과 같이해야한다고 생각한다.

$sm = $this->getServiceLocator(); 
$auth = $sm->get('Navigation'); 

내 IndexController에서 작동하지만 내 AliasSegment에서 작동하지 않는다. '링크'매개 변수를 사용하여 탐색 배열 노드를 찾아야합니다. 나는 해결책을 발견했습니다

편집 할 수 있습니다. 대답은 아래에 있습니다.이 컨트롤러 인 경우, 내가 가지고 module.config.php에

답변

1

OK 체크 아웃, 나는 그것을했습니다. 이 스레드에서 중요한 점은 ZF2: How to get Zend\Navigation inside custom route?입니다.

모든 세그먼트 유형 경로를 사용할 수 있습니다. 그러나 이것은 match 기능에 약간의 수정이 필요할 수 있습니다.

내비게이션의 단일 페이지에 '링크'매개 변수가 있으면 URL이 '링크'문자열로 변환되지만 다른 매개 변수는 뒤에 남습니다. 현재 경로의 기본 URI에 대한 오버레이로 생각하면됩니다.

커스텀 라우트 클래스를 조금 수정해야했습니다. 우선, 네임 스페이스를 Application\Router으로 변경해야했습니다.

여기
// EDIT - file within ModuleName/src/Router/Alias.php 
namespace Application\Router; 

use Traversable; 
use Zend\Mvc\Router\Exception; 
use Zend\Stdlib\ArrayUtils; 
use Zend\Stdlib\RequestInterface as Request; 
use Zend\Mvc\Router\Http; 

class Alias extends Http\Segment 
{ 
    private static $_navigation = null; 

    public function match(Request $request, $pathOffset = null) 
    { 
     $uri = $request->getUri(); 
     $path = $uri->getPath(); 


     $items = self::$_navigation->findAllBy('route', 'node'); 
     $params = null; 

     if($items != null){ 
      $t = sizeof($items); 
      for ($i=0; $i < $t; $i++) { 
       $item = $items[$i]; 
       $params = $item->getParams(); 
       if (isset($params['link']) && $params['link']==$path){ 
        $uri->setPath('/'.$item->getRoute().'/'.$params['id']); 
        $request->setUri($uri); 
        break; 
       } 
      } 
     } 

     return parent::match($request, $pathOffset); 
    } 

    public function setNavigation($navigation){ 
     self::$_navigation = $navigation; 
    } 

    protected function buildPath(array $parts, 
           array $mergedParams, $isOptional, $hasChild) 
    { 

     if(isset($mergedParams['link'])){ 
      return $mergedParams['link']; 
     } 

     return parent::buildPath($parts, $mergedParams, 
               $isOptional, $hasChild); 
    } 

} 

module.config.php의 샘플 일부입니다 :

'navigation' => array(
     // The DefaultNavigationFactory we configured in (1) uses 'default' as the sitemap key 
     'default' => array(
      // And finally, here is where we define our page hierarchy 
      'account' => array(
       'label' => 'Account', 
       'route' => 'node', 
       'params' => array(
          'id' => '2', 
          ), 
       'pages' => array(
        'home' => array(
         'label' => 'Dashboard', 
         'route' => 'node', 
         'params' => array(
            'id' => '8', 
            'link' => '/about/gallery' 
            ), 

        ), 
        'login' => array(
         'label' => 'Sign In', 
         'route' => 'node', 
         'params' => array(
            'id' => '6', 
            'link' => '/signin' 
            ), 

        ), 
        'logout' => array(
         'label' => 'Sign Out', 
         'route' => 'node', 
         'params' => array(
            'id' => '3', 
            ), 
        ), 
       ), 
      ), 
     ), 
    ), 
    'router' => array(
     'routes' => array(

      'home' => array(
       'type' => 'Zend\Mvc\Router\Http\Literal', 
       'options' => array(
        'route' => '/', 
        'defaults' => array(
         'controller' => 'Application\Controller\Index', 
         'action'  => 'index', 
        ), 
       ), 
      ), 
      'node' => array(
       'type' => 'Application\Router\Alias', 
       'options' => array(
        'route' => '/node[/:id]', 
        'constraints' => array(
         'id' => '[0-9]+' 
        ), 
        'defaults' => array(
         '__NAMESPACE__' => 'Application\Controller', 
         'controller' => 'Index', 
         'action'  => 'index', 
         'id'   => '0' 
        ), 
       ), 
       'may_terminate' => true, 
      ), 

     ), 
    ), 
2

unable to fetch or create an instance for Application\Controller\AliasSegment

기대 :

namespace Zend\Mvc\Router\Http;

대해 :

'controllers' => array(
    'invokables' => array(
     '\Application\Controller\AliasSegment' => '\Application\Controller\AliasSegment', 
    ) 
), 

또한 클래스의 네임 스페이스가 조금 이상한 :

namespace Application\Controller; 
+0

내가 네임 스페이스를 변경했지만 작동하지 않았다 감사하지만 나는했습니다 몇 가지 및 변경, 여기에 전체 클래스입니다 않습니다! invokables를 사용하는 것은 불필요한 일입니다. 내 질문을 편집 했으므로 다음을보십시오. – mkatanski

0

R 당신은 단순히 아이의 경로로 문자 경로를 사용할 수 있습니다 /about/about/galery 같은 경로

'about' => array(
    'type' => 'literal', 
    'options' => array(
     'route' => '/about', 
     'defaults' => array(
      'controller' => 'module-controller-about', 
      'action'  => 'index' 
     ) 
    ), 
    'may_terminate' => true, 
    'child_routes' => array(
     'galery' => array(
      'type' => 'literal', 
      'options' => array(
       'route' => '/galery', 
       'defaults' => array(
        'controller' => 'module-controller-galery' 
       ) 
      ) 
     ) 
    ) 
) 

당신이 아마 설정하는 정규식 경로가 /blog/1-my-great-seo-title 같은 URL로 제공 (최저 인 리터럴가 가장 빠르다) .

어쩌면 DASPRiDs Slides from his Router Presentation

+0

글쎄, 아니, 리터럴 라우터 충분하지 않습니다. Zend Navigation을 사용하여 링크를 표시하고 싶습니다. 그리고 그 링크는 예를 들어/node/1 또는/about/gallery 일 수 있습니다. 그래서 탐색 배열에 'link'매개 변수가 있는지 사용자 지정 라우터에서 확인해야합니다. 그렇다면이 링크를 리턴하고 그렇지 않으면 세그먼트 (노드/1)를 리턴하십시오. 내 질문을 봐, 나는 그것을 편집했다. 그것은 거의 작동하지만 나는 사용자 정의 라우터 내에서 탐색 배열을 확인하는 방법을 모른다. – mkatanski