方法1:

php test.php &

这是依赖于终端的,如果terminal终端关闭 , 无论是正常关闭还是非正常关闭 , 这个php进程都会随着终端关闭而关闭 , 其次是代码中如果有echo或者print_r之类的输出文本 , 会被输出到当前的终端窗口中 。

方法2:

nohup php test.php  &

默认情况下,代码中echo或者print_r之类输出的文本会被输出到php代码同级目录的nohup.out文件中,如果你用exit命令或者关闭按钮等正常手段关闭终端 , 该进程不会被关闭,依然会在后台持续运行。

因为echo,print_r等输出语句依赖终端,所以nohup命令默认将输出重新向到文件,不然,如果你的程序有输出,而你却关闭了会话终端,这就导致程序出错退出。

通常的做法是:nohup php test.php > /dev/null 2>&1 &2>&1 将标准错误重定向到标准输出。
/dev/null 将标准输出重定向到空文件,也就是丢弃的意思。

方法3:
setsid 就是set session id,关于setsid
1、要求当前进程不能是进程组组长。
2、会创建一个新的会话和进程组,从而脱离当前会话,并设置当前进程为进程组组长。
3、没有对应的控制终端。

<?php
    // fork子进程
    $pid = pcntl_fork();
    if ( $pid < 0 ) {
	  exit( ' fork error. ' );
	} else if( $pid > 0 ) {
	  exit( ' parent process. ' );
	}
	
	// 创建新会话,设置当前进程为组长
	if ( ! posix_setsid() ) {
	  exit( ' setsid error. ' );
	}
	// fork子进程
	$pid = pcntl_fork();
	if( $pid < 0 ){
	  exit( ' fork error. ' );
	} else if( $pid > 0 ) {
	  exit( ' parent process. ' );
	}

	// 重定向stdout, stderr到日志文件
	global $STDOUT, $STDERR;
	fclose(STDOUT);
	fclose(STDERR);
	
	$log = __DIR__ . '/daemon.txt';
	if(file_exists($log)){
		file_put_contents($log, '');
	}else{
		touch($log, 755);
	}
	
	$handler = fopen($log, "rw+");
	
	$STDOUT = $handler;
	$STDERR = $handler;
	
	for( $i = 1 ; $i <= 100 ; $i++ ){
	  	echo 'loop' . $i . PHP_EOL;
	  	// 此处不要使用 $log,会出现文件内容混论
	    file_put_contents("php://output", $i . "--" . date("Y-m-d H:i:s", time()) . PHP_EOL, FILE_APPEND);
	    sleep(1);
	}

注意:
1、守护进程如果有输出,那么它依然是依赖会话的,关闭会话,守护进程将会出错退出。
2、守护进程的输出是个伪需求,但是不排除某个输出调试忘记注释的情况,可以通过上面的例子将输出定向到文件;一般将echo, print_r等调试信息定向到 console 日志文件,与正常的日志内容分开。
3、守护进程也会在程序出现错误或异常时退出,所以你要在程序里接管错误并捕获异常然后记录到日志。

守护进程的原理
比如,我们在终端中启动了程序 test
./test & 此时它的父进程是 sh 终端进程,如果关闭了窗口,也就是退出了 sh 进程,那么 test 进程会收到 SIGHUP 信号,此信号会导致程序退出。

我们经常看到很多程序使用 -d 参数来使程序成为守护进程,其原理就是:在程序内部对参数进行分析,如果有 -d 参数,就删掉 -d ,并保留其他参数,重新启动自己。

./test arg1 arg2 -d

if 有 -d 参数 {
	./test arg1 arg2
}else{
	...
}

父子关系

sh-100 --> test-101 --> test-102

由于test-101 进程在启动自己的时候就退出了,在Linux下,父进程先于子进程退出,那么子进程就会成为孤儿进程,而成为pid=1的子进程,于是test-102就脱离了 sh 的掌控,因此终端退出就不会导致其退出。