2014-11-01 48 views
0

所以基本上CodeIgniter中有一種方法可以實現異步操作?無論如何,我可以在CodeIgniter中實現類似於新線程的功能嗎?

例如,註冊後我想發送電子郵件。這往往需要一兩秒鐘,用戶需要等待大量的時間。

那麼CodeIgniter或PHP有什麼方法來啓動發送電子郵件(或其他任何操作),並繼續執行腳本而不必等待它結束?

我能想到的唯一方法就是讓某個cron執行獨立於該腳本的行爲。但是腳本中有什麼我能做的嗎?

+0

調用發送電子郵件作爲異步AJAX請求的控制器操作可能是最好的解決方案。這將是瀏覽器中的非阻塞呼叫,這將允許用戶做其他事情。 – 2014-11-01 01:49:11

+0

如果我發起ajax請求,並且用戶在獲得答覆之前重新加載頁面,會發生什麼情況?甚至有可能,或者在頁面可以重新加載之前完成任何AJAX請求? – galdikas 2014-11-01 01:58:11

+0

這很大程度上取決於你是否在Windows或Linux上運行,這兩者都有可能。 – ArtisticPhoenix 2014-11-01 02:01:03

回答

1

您還可以將一個條目添加到像rabbit mq或zero mq這樣的消息隊列中,以便稍後異步處理該消息。看一下react-php也會有幫助。

1

AJAX請求?

您可以異步發送請求到您的服務器,並讓它們被任何你想要的東西觸發。一旦該功能執行並向服務器發出請求,無論用戶是否離開該頁面,該過程都將在服務器上繼續。

例如:

$('#submit-btn').on("click", function() { 

    function signUp(){ 
    var email = $('#subscription').val(); 
    var op1 = $('#option1').val(); 
    var op2 = $('#option2').val(); 

    var formData = new FormData(); 
    formData.append('email', email); 
    formData.append('option_1', op1); 
    formData.append('option_2', op2);  

    $.ajax({ 
     url: '/subscribe', 
     data: formData, 
     processData: false, 
     contentType: false, 
     type: 'POST' 
    }); 
}); 
1

這是我在做CI,

創建index.php文件的副本,將它的根目錄之上,即。它在瀏覽器中無法訪問。在這個索引文件 - 它說:DEFAULT CONTROLLER加入這一行

$routing['controller'] = 'cli'; 

這將鎖定或坐牢是index.php文件只使用cli.php文件中的控制器,用戶在網絡上這樣傾斜啓動該控制器的方法。這對於安全原因很重要。還有其他一些好處,它爲您的後臺腳本提供了獨立的CI環境。例如,您可以設置單獨defined('ENVIRONMENT')您的網站,等等。

cli.php添加這樣的事情

/** 
* 
* <pre> 
* <b>Windows</b> 
*   php -f "{path to index}/index.php" "[arg1]/[arg2]" 
* <b>Linux</b> 
*   /usr/bin/php -f "{path to index}/index.php" "[arg1]/[arg2]" 
*/ 
public function index(){ 
    echo __METHOD__ . "/n"; 
    print_r(func_get_args()); 
} 

的意見是在命令行調用中使用。或者你可以使用我的BGPROCESS類

創建該類

class BgProcess{ 
    /** 
    * 
    * @param string $arg0, $arg1 ... 
    * $arg0 is location of php file to run 
    * $arg1 ..is additional params to send to script 
    */ 
    public function __construct($arg0){ 
     if(stripos(php_uname('s'), 'win') > -1){ 
      $_osWin = true; 
     }else{ 
      $_osWin = false; 
     } 

     $args = func_get_args(); 
     $file = str_replace('\\', '/', array_shift($args)); 
     $script = escapeshellarg($file).' '.escapeshellarg(implode('/', $args)); 
     if(false !== ($phpPath = $this->_getPHPExecutableFromPath($_osWin))){ 
      if($_osWin){  
       $WshShell = new \COM('WScript.Shell'); 
       $cmd = 'cmd /C '.$phpPath.' '.$script; 
       $oExec = $WshShell->Run($cmd, 0, false); 
      }else{ 
       //> /dev/null & 
       $cmd = $phpPath.' -f '.$script.' > /dev/null &'; 
       exec($cmd); 
      } 
     }else{ 
      die('Could not find php executable'); 
     } 
    } 

    /** 
    * 
    * @return string|boolean 
    */ 
    protected function _getPHPExecutableFromPath($_osWin) { 
     $paths = explode(PATH_SEPARATOR, getenv('PATH')); 
     if($_osWin){ 
      foreach ($paths as $path) { 
       if (strstr($path, 'php')){ 
        $php_executable = $path . DIRECTORY_SEPARATOR . 'php.exe'; 
        if(file_exists($php_executable) && is_file($php_executable)){ 
         return $php_executable; 
        } 
       } 
      } 
     }else{ 
      foreach ($paths as $path) { 
       $php_executable = $path . DIRECTORY_SEPARATOR . "php"; 
       if (file_exists($php_executable) && is_file($php_executable)) { 
        return $php_executable; 
       } 
      } 

     } 
     return false; 
    } 
} 

這樣稱呼它

$BG = new BgProcess("{path to index }index.php, $arg1, $arg2 .. etc); 

添加你的代碼,CLI的你通常會在一個控制器。如果不使用索引方法,像這樣調用它。

php -f "{path to index}/index.php" "[method]/[arg2]" 


    $BG = new BgProcess("{path to index }index.php, $method, $arg1 .. etc); 

本質上講,當你在命令行或與BGPROCESS類它的路線就像正常的CI類調用它,也有因爲你是在命令行界面上運行$_SERVER變量和東西一定的差異。但這是做到這一點的「正確」方式。

這是從我設置的所以不知道它會馬上工作,但它應該讓你開始。當你需要的是後臺進程時,RabbitMq有點矯枉過正。順便說一下,這是我的RabbitMq設置的一小部分。兔子是真棒,如果你需要一個全面的排隊系統,但有安裝它和學習曲線與什麼客戶端使用等。

請注意您需要能夠使用runexec命令在PHP中。也不要將用戶輸入放在shell命令的參數中,這是將索引文件移出web訪問位置的主要原因。只能使用正確驗證的輸入來調用它。我確實有escapeshellarg來清理輸入,但我不會僅僅依賴於此。

順便說一下,這是值得幾天的研究在Windows上運行適當的後臺進程。

正如其他人提到的那樣,使用Ajax可以更輕鬆地完成工作,但是您有使用httpd服務器的開銷。這與使用cron運行它相似,但沒有cron。如果您熟悉命令行調用應該與cron調用非常相似,除非您使用捲曲爲yuck

乾杯!

相關問題