PHP를 쉘에서 실행 시킬때(CLI 환경) restart 시키는 방법
PHP를 웹서버를 통해서 실행 시키는 것을 흔히 사용하지만
쉘에서 실행 시키는 경우도 있습니다. 통상 CLI 환경이라고 합니다.
아래는 웹브라우저에 출력을 내보는것이 아니라 쉘에서 실행 시키는 경우 스케줄에 등록하여 매일 재시작 해야 되는 경우 필요한것입니다.
현재 실행 중인 프로그램을 강제 종료하고 스케줄에 의해 다시 실행시크는 형태의 프로그램을 만들어야 할 경우 유용 합니다.
/**
*
* Linux 쉘에서 백그라운드 실행 시킬때 PID 관리를 위한것
*
*/
class PhpRestart
{
private $HOST_NAME = '';
private $TYPE = 'restart';
private $STATUS = '';
private $_PID_ = 0;
private $FILE_PID = '';
function __construct( string $TYPE='' )
{
if ( strlen($TYPE) < 1 ) $TYPE = 'start';
$this->_PID_ = getmypid();
$this->TYPE = $TYPE;
$this->HOST_NAME = php_uname('n');
$this->FILE_PID = __DIR__ . '/testphp_' . $this->_PID_ . '.pid';
if ( $TYPE == 'start' ) {
$this->start();
}
else if ( $TYPE == 'stop' ) {
$this->stop();
}
else if ( $TYPE == 'restart' ) {
$this->restart();
}
}
/**
* 파일이 있으면 kill 처리 후 pid 파일을 생성 한다.
*
* @return [type]
*
*/
private function start() {
if ( is_file($this->FILE_PID) ) $this->kill();
$wrtSize = file_put_contents($this->FILE_PID, $this->_PID_);
echo date('Y-m-d H:i:s ') . "PID 생성: $this->_PID_" . ' / pidFile: ' . $this->FILE_PID . PHP_EOL;
return $wrtSize;
}
private function restart() {
$rUnlink = $this->kill();
$wrtSize = $this->start();
echo date('Y-m-d H:i:s ') . "STATUS: $this->STATUS -> $this->_PID_ / $wrtSize:$this->FILE_PID / HOST_NAME:$this->HOST_NAME \n";
return $wrtSize;
}
private function stop() {
$rUnlink = $this->kill();
echo date('Y-m-d H:i:s ') . "unlink: $rUnlink / 프로그램을 종료 합니다. \n";
exit;
}
private function kill()
{
if ( is_file($this->FILE_PID) )
{
$pid_no = file_get_contents($this->FILE_PID);
$rExec = shell_exec("/bin/kill $pid_no");
$rUnlink = unlink($this->FILE_PID);
echo date('Y-m-d H:i:s ') . "STATUS: $this->STATUS -> $rExec / $rUnlink: $this->FILE_PID \n";
return $rUnlink;
}
else {
echo date('Y-m-d H:i:s ') . "$this->FILE_PID 파일이 없습니다. " . PHP_EOL;
return false;
}
}
public function get_pid() {
return $this->_PID_;
}
public function get_status() {
return $this->STATUS;
}
public function get_pidfile() {
return $this->FILE_PID;
}
}
$oPhpExec = new PhpRestart( 'restart' );
echo date('Y-m-d H:i:s ') . '생성된 pid 값은: ' . $oPhpExec->get_pid() . '입니다.' . PHP_EOL;
* 클래스가 복잡해 보인다면 간단한 아래를 참고
- 쉘에서 실행할때 프로세스(pid) 저장후 재시작(restart) 할때 kill(종료) 시키기 > PHP
* 클래스 만들때 :: 두개 찍어서 직접 메소드 호출하고 자 할때는 아래를 참고하세요.
중요한것은 퍼블릭 이어야 합니다.
- 모던php 사용시 흔하게 볼 수 있는 한가지 static > PHP
class Parent2 {
function getNew() : string {
return 'parent - getNew print: ' . __METHOD__ . PHP_EOL;
}
}
class Child extends Parent2
{
static $ymd2 = ''; //
public static function setYmd( string $ymd='' ) {
if (strtotime($ymd) < 1) {
$ymd = date('Y-m-d H:i:s');
}
self::$ymd2 = $ymd;
}
public function getYmd() {
return self::$ymd2;
}
public function get_parent_new() {
return parent::getNew();
}
}
echo date('Y-m-d H:i:s ') . '설정: ' . Child::setYmd( 'testYmd' ) . PHP_EOL;
echo date('Y-m-d H:i:s ') . '출력1: ' . Child::getYmd() . PHP_EOL;
echo date('Y-m-d H:i:s ') . '출력2: ' . Child::get_parent_new() . PHP_EOL;
범위확인 연산자에 - 더블콜론에 대해선 메뉴얼을 보시는것이 좋습니다.
아래는 맨위에 있는것을 더블콜론으로 만들어 보았습니다. static가 아니면 접근이 되도 VSCODE에선 파란색줄이 보입니다.
접근과 별도의 객체 생성이 아닌 직접접근을 하려면 어딘가에 있어야 하니 가져올 수 있는 권한이 있어야 한 다는것을 생각하면 됩니다.
/**
*
* Linux 쉘에서 백그라운드 실행 시킬때 PID 관리를 위한것
*
*/
class PhpRestart
{
static $HOST_NAME = '';
static $TYPE = 'restart';
static $_PID_ = 0;
static $FILE_PID = '';
public static function set_config( string $TYPE='' )
{
if ( strlen($TYPE) < 1 ) $TYPE = 'start';
self::$_PID_ = getmypid();
self::$TYPE = $TYPE;
self::$HOST_NAME = php_uname('n');
self::$FILE_PID = __DIR__ . '/testphp_' . self::$_PID_ . '.pid';
}
/**
* 파일이 있으면 kill 처리 후 pid 파일을 생성 한다.
*
* @return [type]
*
*/
static function start() {
if ( is_file(self::$FILE_PID) ) self::kill();
$wrtSize = file_put_contents(self::$FILE_PID, self::$_PID_);
echo date('Y-m-d H:i:s ') . self::$TYPE . " PID 생성: " . self::$_PID_ . ' / pidFile: ' . self::$FILE_PID . PHP_EOL;
return $wrtSize;
}
static function restart() {
$rUnlink = self::kill();
$wrtSize = self::start();
echo date('Y-m-d H:i:s ') . self::$TYPE . " PID: " . self::$_PID_ . " / $wrtSize:" . self::$FILE_PID . " / HOST_NAME:" . self::$HOST_NAME . PHP_EOL;;
return $wrtSize;
}
static function stop() {
$rUnlink = self::kill();
echo date('Y-m-d H:i:s ') . self::$TYPE . " unlink: $rUnlink / 프로그램을 종료 합니다. \n";
exit;
}
static function kill()
{
if ( is_file(self::$FILE_PID) )
{
$pid_no = file_get_contents(self::$FILE_PID);
$rExec = shell_exec("/bin/kill $pid_no");
$rUnlink = unlink(self::$FILE_PID);
echo date('Y-m-d H:i:s ') . self::$TYPE . " rExec: $rExec / $rUnlink: " . self::$FILE_PID . PHP_EOL;
return $rUnlink;
}
else {
echo date('Y-m-d H:i:s ') . self::$TYPE . " FILE_PID: " . self::$FILE_PID . " 파일이 없습니다. " . PHP_EOL;
return false;
}
}
public function get_pid() {
return self::$_PID_;
}
public function get_pidfile() {
return self::$FILE_PID;
}
}
// 실행방법 1
PhpRestart::set_config('start');
PhpRestart::start();
echo date('Y-m-d H:i:s ') . PhpRestart::$TYPE . ' 생성된 pid 값은: ' . PhpRestart::get_pid() . '입니다.' . PHP_EOL;
// 실행방법 2
$oPhpExec = new PhpRestart();
$oPhpExec->set_config('start');
$oPhpExec->start();
echo date('Y-m-d H:i:s ') . $oPhpExec->TYPE . ' 생성된 pid 값은: ' . $oPhpExec->get_pid() . '입니다.' . PHP_EOL;