Thinkphp5 命令行執行代碼

轉載地址:https://blog.csdn.net/abraa/arti

說明:如何用命令行執行正常的tp5代碼


前言:
      在此之前,你應當能正常使用linux php命令行,包括但不限於php安裝,環境變量配置等...
      

簡單示例執行:
      官網文檔關於命令行的介紹非常簡短,沒有接觸過很容易雲裏霧裏,不知所謂.當然你也可以看它的源碼示例,調試幾遍也就基本瞭解了.
      這篇文章主要是用於你不想去調試源碼,或者參考使用.
      hello word !
      我們構建一個PHP命令 hello 
      #>   php think hello  
      hello word !
      代碼示例
首先在application 文件夾下建立一個新文件夾command(用來放我們自定義的Tp命令) 我們取名叫Hello.php(隨意取)

<?php
namespace app\command;
 
 
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\Request;
 
 
class Hello extends Command{                            //繼承think\console\Command
 
 
    /**
     * 重寫configure
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this->setName('hello')
            ->setDescription('hello word !');
    }
 
 
    /**
     * 重寫execute
     * {@inheritdoc}
     */
    protected function execute(Input $input, Output $output)
    {
        $output->writeln('hello word !');
    }
}
?>

這樣我們簡單的hello命令就完成了.
可是現在我們cd 到tp根目錄(就是有think這個php文件的目錄) 執行php think hello 報錯 : Command "hello" is not defined.


這是因爲我們還缺少一個配置文件
編輯 application/command.php(沒有就新建) 加上Hello.php文件的namespace

<?php
return [
    "app\\command\\Hello",            
];
 
?>

好了 ,現在我們的hello命令完成了. 是不是很簡單?


現在我們開始進階版.
我們如何像瀏覽器訪問那樣用命令行去執行php代碼呢?
我們修改hello命令,還是輸出一個hello word !
現在我們有一個index模塊(module) , index控制器(controller) , index方法(action)
<?php
namespace app\index\controller;
 
class Index
{
    public function index()
    {
       return 'hello word !';
    }
}
?>

hello命令代碼
<?php
namespace app\command;
 
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\Request;
 
class Hello extends Command{                            //繼承think\console\Command
 
    /**
     * 重寫configure           ---定義命令
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this->setName('hello')                                 //命令名稱
            ->setDefinition([                           //Option 和 Argument都可以有多個, Argument的讀取和定義的順序有關.請注意
                new Option('option', 'o', Option::VALUE_OPTIONAL, "命令option選項"),       //使用方式  php think hello  --option test 或 -o test
                new Argument('test',Argument::OPTIONAL,"test參數"),                        //使用方式    php think hello  test1 (將輸入的第一個參數test1賦值給定義的第一個Argument參數test)
                //...
            ])
            ->setDescription('hello word !');                               //命令描述
    }
 
    /**
     * 重寫execute         ---執行入口
     * {@inheritdoc}
     */
    protected function execute(Input $input, Output $output)
    {                                                           //Input 用於獲取輸入信息    Output用於輸出信息
        $request = Request::instance([                          //如果在希望代碼中像瀏覽器一樣使用input()等函數你需要示例化一個Request並手動賦值
            'get'=>$input->getArguments(),                    //示例1: 將input->Arguments賦值給Request->get  在代碼中可以直接使用input('get.')獲取參數
            'route'=>$input->getOptions()                       //示例2: 將input->Options賦值給Request->route   在代碼中可以直接使用request()->route(false)獲取 
            //...
        ]);
        $request->module("Index");                          //綁定當前模塊爲Index  只有綁定模塊你在代碼中使用model('user')等函數纔不需要指定模塊model('index/user')
//        $request->controller('index')->action('index');       //綁定controller和action
 
        $output->writeln(controller('index/Index')->index());       //執行index模塊index控制器index函數 ,並輸出返回值
    }
}

輸出 hello word !
基本使用就到這了,如果希望瞭解更多詳細用法可以去看源碼和tp實現的幾個命令示例,還是相當明瞭的. 
當然你也可以繼續看下去,但不會太過詳細,只會有個基本介紹


文件架構詳解:
我們從文件入口目錄結構講起:
---------------
   |-think   入口文件
   |-thinkphp   框架目錄
      |-console.php 命令行入口
      |-library
          |-think
     |-App.php  ---App::initCommon() ;這是tp的初始化函數  只需要執行它你就可以使用整個tp5框架的功能了.
     |-Console.php    ---Console::init(); 這是tp的命令加載函數  執行它就可以使用tp的自定義命令了.
      ....
略過框架實現的介紹(有興趣的自己去看源碼),簡要說一下常用到卻少接觸的幾個文件,畢竟我們的目的只是使用
1.首先當然是think\console\Command :
   執行命令的入口文件除了框架自己定義的execute() 也可以在初始化initialize(Input $input, Output $output)時通過$this->setCode(callback fn);來手動設置執行入口 (callback怎麼用? 參考call_user_func())(比如調用$this->index() 就是: $this->setCode([$this,'index']);)
    這樣就可以在一個命令裏邏輯區分使用不同的入口
 
2.input :
    好像沒啥好講得源碼註釋很詳細. 只需要知道你所有的輸入都在這個裏面取就好了.   主要分成2塊 Option 和 Argument 怎麼定義怎麼用就隨你了.


3.request :
   雖然request放在這裏感覺有點不大合適,但誰讓tp helper函數都是基於request的呢? 雖然不需要它也能使用但要有和瀏覽器同樣的體驗(比如一樣的代碼能在瀏覽器和命令行同時執行),還是自己手動實例化一個request吧.
   挺多的自己去看源碼吧,註釋挺詳細的...
   一般也就instance(['post'=>[],'get'=>[]...]) 實例化並綁定幾個參數 再$request->module('index')綁定下當前模塊就差不多了.畢竟像$_SERVER之類的自己設也沒啥意義

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章