programing

명령줄에서 Zend Framework 작업 실행

telebox 2023. 8. 20. 10:45
반응형

명령줄에서 Zend Framework 작업 실행

명령줄에서 일부 파일을 생성하기 위해 Zend Framework 작업을 실행하고 싶습니다.이것이 가능하며 ZF를 사용하는 기존 웹 프로젝트에 대해 얼마나 변경해야 합니까?

감사합니다!

갱신하다

원한다면 https://github.com/akond/zf-cli 에서 이 모든 코드를 ZF 1.12용으로 수정할 수 있습니다.

#1 솔루션은 괜찮지만 때로는 더 정교한 솔루션을 원할 수도 있습니다.특히 하나 이상의 CLI 스크립트가 필요한 경우에는 더욱 그렇습니다.당신이 허락한다면 다른 해결책을 제안하겠습니다.

우선, 부트스트랩을 착용합니다.php

protected function _initRouter ()
{
    if (PHP_SAPI == 'cli')
    {
        $this->bootstrap ('frontcontroller');
        $front = $this->getResource('frontcontroller');
        $front->setRouter (new Application_Router_Cli ());
        $front->setRequest (new Zend_Controller_Request_Simple ());
    }
}

이 방법은 기본 라우터에서 자체 라우터 Application_Router_Cli에 대한 디스패치 제어를 차단합니다.

참고로 웹 인터페이스에 대해 _initRoutes에서 자체 경로를 정의한 경우 명령줄 모드에서 해당 경로를 무력화할 수 있습니다.

protected function _initRoutes ()
{
    $router = Zend_Controller_Front::getInstance ()->getRouter ();
    if ($router instanceof Zend_Controller_Router_Rewrite)
    {
        // put your web-interface routes here, so they do not interfere
    }
}

클래스 Application_Router_Cli(애플리케이션 접두사에 대해 자동 로드가 켜져 있다고 가정함)는 다음과 같이 보일 수 있습니다.

class Application_Router_Cli extends Zend_Controller_Router_Abstract
{
    public function route (Zend_Controller_Request_Abstract $dispatcher)
    {
        $getopt = new Zend_Console_Getopt (array ());
        $arguments = $getopt->getRemainingArgs ();
        if ($arguments)
        {
            $command = array_shift ($arguments);
            if (! preg_match ('~\W~', $command))
            {
                $dispatcher->setControllerName ($command);
                $dispatcher->setActionName ('cli');
                unset ($_SERVER ['argv'] [1]);

                return $dispatcher;
            }

            echo "Invalid command.\n", exit;

        }

        echo "No command given.\n", exit;
    }


    public function assemble ($userParams, $name = null, $reset = false, $encode = true)
    {
        echo "Not implemented\n", exit;
    }
}

이제 응용프로그램을 실행하여 간단히 실행할 수 있습니다.

php index.php backup

이 경우 백업 컨트롤러의 cliAction 메서드가 호출됩니다.

class BackupController extends Zend_Controller_Action
{
    function cliAction ()
    {
        print "I'm here.\n";
    }
}

Application_Router_Cli 클래스를 수정하여 "cli" 작업이 매번 수행되는 것이 아니라 사용자가 추가 매개 변수를 통해 선택한 작업을 수행할 수도 있습니다.

그리고 마지막으로 한 가지.화면에 HTML 코드가 표시되지 않도록 명령줄 인터페이스에 대한 사용자 지정 오류 처리기 정의

부트스트랩에서.php

protected function _initError ()
{
    $error = $frontcontroller->getPlugin ('Zend_Controller_Plugin_ErrorHandler');
    $error->setErrorHandlerController ('index');

    if (PHP_SAPI == 'cli')
    {
        $error->setErrorHandlerController ('error');
        $error->setErrorHandlerAction ('cli');
    }
}

ErrorController.php에 있습니다.

function cliAction ()
{
    $this->_helper->viewRenderer->setNoRender (true);

    foreach ($this->_getParam ('error_handler') as $error)
    {
        if ($error instanceof Exception)
        {
            print $error->getMessage () . "\n";
        }
    }
}

사실 여러분이 생각하는 것보다 훨씬 쉽습니다.부트스트랩/애플리케이션 구성 요소와 기존 구성은 MVC 스택과 HTTP 요청에서 호출되는 불필요한 가중치를 피하면서 CLI 스크립트와 함께 재사용할 수 있습니다.이것은 wget을 사용하지 않는 것의 한 가지 장점입니다.

공용 인덱스와 마찬가지로 스크립트를 시작합니다.php:

<?php

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH',
              realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV',
              (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
                                         : 'production'));

require_once 'Zend/Application.php';
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/config.php'
);

//only load resources we need for script, in this case db and mail
$application->getBootstrap()->bootstrap(array('db', 'mail'));

그런 다음 MVC 응용 프로그램에서와 마찬가지로 ZF 리소스를 계속 사용할 수 있습니다.

$db = $application->getBootstrap()->getResource('db');

$row = $db->fetchRow('SELECT * FROM something');

CLI 스크립트에 구성 가능한 인수를 추가하려면 Zend_Console_Getopt를 확인하십시오.

MVC 응용 프로그램에서도 호출할 수 있는 공통 코드가 있는 경우 개체로 묶고 MVC 및 명령줄 응용 프로그램에서 해당 개체의 메서드를 호출합니다.이것이 일반적인 모범 사례입니다.

방금 제 CP에 태그된 것을 봤습니다.이 게시물을 우연히 발견하고 ZF2를 사용하고 있다면 훨씬 쉬워졌습니다.module.config를 편집하기만 하면 됩니다.php의 경로는 다음과 같습니다.

/**
 * Router
 */

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

        // .. these are your normal web routes, look further down
    ),
),

/**
 * Console Routes
 */
'console' => array(
    'router' => array(
        'routes' => array(

            /* Sample Route */
            'do-cli' => array(
                'options' => array(
                    'route'    => 'do cli',
                    'defaults' => array(
                        'controller' => 'Application\Controller\Index',
                        'action'     => 'do-cli',
                    ),
                ),
            ),
        ),    
    ),
),

위의 구성을 사용하여 응용 프로그램 모듈 아래의 IndexController.php에서 doCliAction을 정의합니다.명령행에서 실행하는 것은 케이크입니다.

php index.https do cli

됐어요! 훨씬 부드럽게.

위의 솔루션은 최상의 상태에 있지만 사용자 환경에서 해당 스크립트가 작동하지 않을 수 있는 몇 가지 세부 사항이 있습니다.그의 답변에 대한 다음과 같은 수정 사항을 고려해 보십시오.

부트스트랩.php

protected function _initRouter()
{
    if( PHP_SAPI == 'cli' )
    {
        $this->bootstrap( 'FrontController' );
        $front = $this->getResource( 'FrontController' );
        $front->setParam('disableOutputBuffering', true);
        $front->setRouter( new Application_Router_Cli() );
        $front->setRequest( new Zend_Controller_Request_Simple() );
    }
}

init 오류는 위에서 설명한 바와 같이 기본 구성을 변경하지 않으면 오류 처리기가 아직 인스턴스화되지 않았을 수 있습니다.

protected function _initError ()
{
    $this->bootstrap( 'FrontController' );
    $front = $this->getResource( 'FrontController' );
    $front->registerPlugin( new Zend_Controller_Plugin_ErrorHandler() );
    $error = $front->getPlugin ('Zend_Controller_Plugin_ErrorHandler');
    $error->setErrorHandlerController('index');

    if (PHP_SAPI == 'cli')
    {
        $error->setErrorHandlerController ('error');
        $error->setErrorHandlerAction ('cli');
    }
}

명령줄에서 둘 이상의 매개 변수를 병합할 수도 있습니다. 기본적인 예는 다음과 같습니다.

class Application_Router_Cli extends Zend_Controller_Router_Abstract
{
    public function route (Zend_Controller_Request_Abstract $dispatcher)
    {
        $getopt     = new Zend_Console_Getopt (array ());
        $arguments  = $getopt->getRemainingArgs();

        if ($arguments)
        {
            $command = array_shift( $arguments );
            $action  = array_shift( $arguments );
            if(!preg_match ('~\W~', $command) )
            {
                $dispatcher->setControllerName( $command );
                $dispatcher->setActionName( $action );
                $dispatcher->setParams( $arguments );
                return $dispatcher;
            }

            echo "Invalid command.\n", exit;

        }

        echo "No command given.\n", exit;
    }


    public function assemble ($userParams, $name = null, $reset = false, $encode = true)
    {
        echo "Not implemented\n", exit;
    }
}

마지막으로 컨트롤러에서 호출하는 작업은 컨트롤러 제거로 인해 고립된 매개 변수와 CLI 라우터의 작업을 사용합니다.

public function echoAction()
{
    // disable rendering as required
    $database_name     = $this->getRequest()->getParam(0);        
    $udata             = array();

    if( ($udata = $this->getRequest()->getParam( 1 )) )
        $udata         = explode( ",", $udata );

    echo $database_name;
    var_dump( $udata );
}

그런 다음 다음 CLI 명령을 호출할 수 있습니다.

php index.php Controller Action ....

예를 들어, 위와 같이:

php index.php Controller echo database123 this,becomes,an,array

보다 강력한 필터링/회피 기능을 구현하고 싶지만, 이는 빠른 구성 요소입니다.이것이 도움이 되길 바랍니다!

한 가지 옵션은 원하는 작업을 호출하는 데 사용하는 URL에서 위젯을 수행하여 이를 조작할 수 있습니다.

wget의 -O 옵션을 사용하여 출력을 저장할 수 없습니다.하지만 wget은 분명히 해결책이 아닙니다.대신 CLI를 사용하는 것을 선호합니다.

오류 예외가 오류 컨트롤러에 의해 렌더링되지 않는 경우를 제외하고는 코드 아이디어가 잘 작동합니다.

public function cliAction() {
  $this->_helper->layout->disableLayout();
  $this->_helper->viewRenderer->setNoRender(true);

  foreach ($this->_getParam('error_handler') as $error) {
    if ($error instanceof Exception) {
      print "cli-error: " . $error->getMessage() . "\n";
    }
  }
}

그리고 Application_Router_Cli에서 echo 및 die 문을 주석 처리합니다.

public function assemble($userParams, $name = null, $reset = false, $encode = true) {
//echo "Not implemented\n";
}

명령줄에서 일반적으로 사용하는 것처럼 PHP를 사용할 수 있습니다.PHP에서 스크립트를 호출하고 스크립트에서 작업을 설정하면 원하는 대로 실행할 수 있습니다.

정말 간단할 것입니다.이것은 실제로 의도된 용도는 아니지만, 당신이 원한다면 이렇게 할 수 있습니다.

예를들면

 php script.php 

여기를 읽어 보십시오. http://php.net/manual/en/features.commandline.php

OS가 Linux인 경우 wget 명령을 사용할 수 있습니다.예:

wget http://example.com/controller/action

http://linux.about.com/od/commands/l/blcmdl1_wget.htm 을 참조하십시오.

업데이트:

다음과 같은 간단한 bash 스크립트를 작성할 수 있습니다.

if wget http://example.com/controller/action
    echo "Hello World!" > /home/wasdownloaded.txt
else
    "crap, wget timed out, let's remove the file."
    rm /home/wasdownloaded.txt
fi

그런 다음 PHP로 할 수 있습니다.

if (true === file_exists('/home/wasdownloaded.txt') {
    // to check that the 
}

이게 도움이 되길 바랍니다.

wget 명령을 사용했습니다.

wget http://example.com/module/controller/action -O /dev/null

-O /dev/null에는 다음과 같이 .

언급URL : https://stackoverflow.com/questions/2325338/running-a-zend-framework-action-from-command-line

반응형