PHP 使用 exec 搭配 MozJPEG 的一些心得

环境 CentOS 7 PHP 7.2.6

查看 php 所在用户与用户组

为 www:www

将 www 用户添加至 root 权限

visudo
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
www     ALL=(ALL) NOPASSWD: ALL

允许 root 用户执行任何命令在任何位置。NOPASSWD  后为执行哪些命令不用输入密码

reboot 重启系统

PHP 测试命令

echo exec('php -v',$a1,$b1);
dump($a1);dump($b1);

echo exec('sudo /opt/mozjpeg/bin/cjpeg -version',$a2,$b2);
dump($a2);dump($b2);

echo exec('sudo /opt/mozjpeg/bin/cjpeg -quality 60 -debug /home/wwwroot/hi.unetu.net/public/tmp/uploads/1.jpeg > /home/wwwroot/hi.unetu.net/public/uploads/1.jpeg',$a3,$b3);
dump($a3);dump($b3);

die();

返回结果

exec 中第三个参数为 0 表示执行成功,其他值如 1 表示失败,上述代码表示执行成功但第二和第三个命令没有返回值也没有输出值

其中第三条 mozjpeg/cjpeg 的压缩图片执行成功

如果想要返回值,查找了一下可以使用管道,在命令添加 2>&1,尝试如下

返回结果

第二条输出了语句,第二条和第三条也都执行成功,但第三条的图片损坏了无法预览

这和在命令行里使用相同命令执行的结果一致

其他尝试

第三条 MozJPEG 如果原图片损坏,则第三条返回 int(1),表示执行失败

参考文献

浅谈PHP的exec()函数无返回值排查方法

https://www.jb51.net/article/110108.htm

PHPExcel 超过 26 列 解决方法

ThinkPHP 3.2 使用 PHPExcel

使用 chr(ord(‘A’)++) 的方法进行 Excel 列的自增,当列数超过26列时,会报如下错误

Invalid cell coordinate [1
错误位置
FILE: E:\wwwroot\wanaioa.a.cc\ThinkPHP\Library\Vendor\Excel\PHPExcel\Cell.php  LINE: 539

原因是 ord(‘Z’) 为 90,当 chr(91) 时为 string(1) “[“

但在 Excel 中应为 AA

解决方法是使用 PHPExcel 自带函数 stringFromColumnIndex

调用方法

\PHPExcel_Cell::stringFromColumnIndex(27);

源码为

/**
 *	String from columnindex
 *
 *	@param	int $pColumnIndex Column index (base 0 !!!)
 *	@return	string
 */
public static function stringFromColumnIndex($pColumnIndex = 0)
{
	//	Using a lookup cache adds a slight memory overhead, but boosts speed
	//	caching using a static within the method is faster than a class static,
	//		though it's additional memory overhead
	static $_indexCache = array();

	if (!isset($_indexCache[$pColumnIndex])) {
		// Determine column string
		if ($pColumnIndex < 26) {
			$_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex);
		} elseif ($pColumnIndex < 702) {
			$_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) .
										  chr(65 + $pColumnIndex % 26);
		} else {
			$_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) .
										  chr(65 + ((($pColumnIndex - 26) % 676) / 26)) .
										  chr(65 + $pColumnIndex % 26);
		}
	}
	return $_indexCache[$pColumnIndex];
}

路径 

ThinkPHP/Library/Vendor/Excel/PHPExcel/Cell.php

封装一个 PHPExcel 的导出方法

本篇以 ThinkPHP 为示例

public function getExcel($property,$headArr,$data){

	Vendor('Excel.PHPExcel');
	$objPHPExcel = new \PHPExcel();
	$objPHPExcel
		-> getProperties()
		-> setCreator($property['creator'])
		-> setLastModifiedBy($property['last'])
		-> setTitle($property['title'])
		-> setSubject($property['subject'])
		-> setDescription($property['description'])
		-> setKeywords($property['keywords'])
		-> setCategory($property['category']);

	$column = 1;
	$span = ord("A");
	foreach($headArr as $v){
		$j = chr($span);
		$objPHPExcel->setActiveSheetIndex(0) -> setCellValue($j.$column,$v);
		$span ++;
	}

	$column ++;
	$objActSheet = $objPHPExcel->getActiveSheet();
	foreach($data as $key => $rows){
		$span = ord('A');
		foreach($rows as $keyName => $value){
			$j = chr($span);
			$objActSheet->setCellValue($j.$column, $value);
			$span ++;
		}
		$column ++;
	}

	$objPHPExcel->setActiveSheetIndex(0);

	ob_end_clean();
	ob_start();

	header("Content-Type: application/force-download");
	header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
	header("Content-Disposition:attachment;filename =" . str_ireplace('+', '%20', URLEncode($fileName)).'.xlsx');
	header('Cache-Control: max-age=0');

	$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
	$objWriter -> save('php://output');
	exit ;
}

调用

public function _index_export(){
	$property = array('title'=>'测试');
	$headArr = array('好','坏');
	$data = array(
		array(
			3,4
		),
		array(
			5,6
		)
	);
	$this->getExcel($property,$headArr,$data);
}

优化当超过 26 列

public function getExcel($property,$headArr,$data){

	Vendor('Excel.PHPExcel');
	$objPHPExcel = new \PHPExcel();
	$objPHPExcel
		-> getProperties()
		-> setCreator($property['creator'])
		-> setLastModifiedBy($property['last'])
		-> setTitle($property['title'])
		-> setSubject($property['subject'])
		-> setDescription($property['description'])
		-> setKeywords($property['keywords'])
		-> setCategory($property['category']);

	$column = 1;
	$span = 0;
	foreach($headArr as $v){
		$letter = \PHPExcel_Cell::stringFromColumnIndex($span);
		$objPHPExcel->setActiveSheetIndex(0) -> setCellValue($letter.$column,$v);
		$span ++;
	}

	$objActSheet = $objPHPExcel->getActiveSheet();
	foreach($data as $key => $rows){
		$column ++;
		$span = 0;
		foreach($rows as $keyName => $value){
			$letter = \PHPExcel_Cell::stringFromColumnIndex($span);
			$objActSheet->setCellValue($letter.$column, $value);
			$span ++;
		}
	}

	$objPHPExcel->setActiveSheetIndex(0);

	ob_end_clean();
	ob_start();

	header("Content-Type: application/force-download");
	header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
	header("Content-Disposition:attachment;filename =" . str_ireplace('+', '%20', URLEncode($property['title'])).'.xlsx');
	header('Cache-Control: max-age=0');

	$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
	$objWriter -> save('php://output');
	exit ;
}

可以设置列宽的一种方法

public function exportExcel($expTitle,$expCellName,$expTableData){
	$xlsTitle = iconv('utf-8', 'gb2312', $expTitle);//文件名称
	$fileName = $expTitle.date('_Ymd_His');//or $xlsTitle 文件名称可根据自己情况设定
	$cellNum = count($expCellName);
	$dataNum = count($expTableData);
	Vendor('Excel.PHPExcel');
	$objPHPExcel = new \PHPExcel();
	$cellName = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ');
	// $objPHPExcel->getActiveSheet(0)->mergeCells('A1:'.$cellName[$cellNum-1].'1');//合并单元格
	// $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', $expTitle.'  Export time:'.date('Y-m-d H:i:s'));//第一行标题
	for($i=0;$i<$cellNum;$i++){
		$objPHPExcel->setActiveSheetIndex(0)->setCellValue($cellName[$i].'1', $expCellName[$i][1]);
		$objPHPExcel->getActiveSheet()->getColumnDimension($cellName[$i])->setWidth($expCellName[$i][2]); //设置宽度
	}
	// Miscellaneous glyphs, UTF-8
	for($i=0;$i<$dataNum;$i++){
		for($j=0;$j<$cellNum;$j++){
			$objPHPExcel->getActiveSheet(0)->setCellValue($cellName[$j].($i+2), $expTableData[$i][$expCellName[$j][0]]);
		}
	}
	header('pragma:public');
	header('Content-type:application/vnd.ms-excel;charset=utf-8;name="'.$xlsTitle.'.xls"');
	header("Content-Disposition:attachment;filename=$fileName.xls");//attachment新窗口打印inline本窗口打印
	$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
	$objWriter->save('php://output');
	exit;
}

调用

public function dumpLogsExcel(){
	//查询数据
	$where['member_card'] = 123456;
	$xlsData = array();//二维数组
	//构建excel
	$xlsName  = "用户评价信息表";
	$xlsCell  = array(
		array('GongSiMc','门店名称',20),
		array('order_num','保养单号',20),
		array('wx_name','微信名',20),
		array('member_card','会员卡号',15),
		array('is_good_name','是否满意',10),
		array('evaluate_item','具体评价',40),
		array('score','得分',10),
		array('create_time','创建时间',20),
	);
	$this->exportExcel($xlsName,$xlsCell,$xlsData);
}

PHP 强制下载类 不使用浏览器预览图片、PDF 等

<?php
namespace download;

class ForceDownload
{
	/**
	 * Force Download
	 *
	 * Generates headers that force a download to happen
	 *
	 * @param	string	filename
	 * @param	mixed	the data to be downloaded
	 * @param	bool	whether to try and send the actual file MIME type
	 * @return	void
	 */
	public function force_download($filename = '', $data = '', $set_mime = FALSE)
	{
		if ($filename === '' OR $data === '')
		{
			return;
		}
		elseif ($data === NULL)
		{
			if ( ! @is_file($filename) OR ($filesize = @filesize($filename)) === FALSE)
			{
				return;
			}

			$filepath = $filename;
			$filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename));
			$filename = end($filename);
		}
		else
		{
			$filesize = strlen($data);
		}

		// Set the default MIME type to send
		$mime = 'application/octet-stream';

		$x = explode('.', $filename);
		$extension = end($x);

		if ($set_mime === TRUE)
		{
			if (count($x) === 1 OR $extension === '')
			{
				/* If we're going to detect the MIME type,
				 * we'll need a file extension.
				 */
				return;
			}

			// Load the mime types
			$mimes =& self::get_mimes();

			// Only change the default MIME if we can find one
			if (isset($mimes[$extension]))
			{
				$mime = is_array($mimes[$extension]) ? $mimes[$extension][0] : $mimes[$extension];
			}
		}

		/* It was reported that browsers on Android 2.1 (and possibly older as well)
		 * need to have the filename extension upper-cased in order to be able to
		 * download it.
		 *
		 * Reference: http://digiblog.de/2011/04/19/android-and-the-download-file-headers/
		 */
		if (count($x) !== 1 && isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/Android\s(1|2\.[01])/', $_SERVER['HTTP_USER_AGENT']))
		{
			$x[count($x) - 1] = strtoupper($extension);
			$filename = implode('.', $x);
		}

		if ($data === NULL && ($fp = @fopen($filepath, 'rb')) === FALSE)
		{
			return;
		}

		// Clean output buffer
		if (ob_get_level() !== 0 && @ob_end_clean() === FALSE)
		{
			@ob_clean();
		}

		// Generate the server headers
		header('Content-Type: '.$mime);
		header('Content-Disposition: attachment; filename="'.$filename.'"');
		header('Expires: 0');
		header('Content-Transfer-Encoding: binary');
		header('Content-Length: '.$filesize);
		header('Cache-Control: private, no-transform, no-store, must-revalidate');

		// If we have raw data - just dump it
		if ($data !== NULL)
		{
			exit($data);
		}

		// Flush 1MB chunks of data
		while ( ! feof($fp) && ($data = fread($fp, 1048576)) !== FALSE)
		{
			echo $data;
		}

		fclose($fp);
		exit;
	}

    public static function &get_mimes()
    {
        static $_mimes;

        if (empty($_mimes))
        {
            $_mimes = array(
                'hqx'	=>	array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
                'cpt'	=>	'application/mac-compactpro',
                'csv'	=>	array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'),
                'bin'	=>	array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'),
                'dms'	=>	'application/octet-stream',
                'lha'	=>	'application/octet-stream',
                'lzh'	=>	'application/octet-stream',
                'exe'	=>	array('application/octet-stream', 'application/x-msdownload'),
                'class'	=>	'application/octet-stream',
                'psd'	=>	array('application/x-photoshop', 'image/vnd.adobe.photoshop'),
                'so'	=>	'application/octet-stream',
                'sea'	=>	'application/octet-stream',
                'dll'	=>	'application/octet-stream',
                'oda'	=>	'application/oda',
                'pdf'	=>	array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'),
                'ai'	=>	array('application/pdf', 'application/postscript'),
                'eps'	=>	'application/postscript',
                'ps'	=>	'application/postscript',
                'smi'	=>	'application/smil',
                'smil'	=>	'application/smil',
                'mif'	=>	'application/vnd.mif',
                'xls'	=>	array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'),
                'ppt'	=>	array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'),
                'pptx'	=> 	array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'),
                'wbxml'	=>	'application/wbxml',
                'wmlc'	=>	'application/wmlc',
                'dcr'	=>	'application/x-director',
                'dir'	=>	'application/x-director',
                'dxr'	=>	'application/x-director',
                'dvi'	=>	'application/x-dvi',
                'gtar'	=>	'application/x-gtar',
                'gz'	=>	'application/x-gzip',
                'gzip'  =>	'application/x-gzip',
                'php'	=>	array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'),
                'php4'	=>	'application/x-httpd-php',
                'php3'	=>	'application/x-httpd-php',
                'phtml'	=>	'application/x-httpd-php',
                'phps'	=>	'application/x-httpd-php-source',
                'js'	=>	array('application/x-javascript', 'text/plain'),
                'swf'	=>	'application/x-shockwave-flash',
                'sit'	=>	'application/x-stuffit',
                'tar'	=>	'application/x-tar',
                'tgz'	=>	array('application/x-tar', 'application/x-gzip-compressed'),
                'z'	=>	'application/x-compress',
                'xhtml'	=>	'application/xhtml+xml',
                'xht'	=>	'application/xhtml+xml',
                'zip'	=>	array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'),
                'rar'	=>	array('application/x-rar', 'application/rar', 'application/x-rar-compressed'),
                'mid'	=>	'audio/midi',
                'midi'	=>	'audio/midi',
                'mpga'	=>	'audio/mpeg',
                'mp2'	=>	'audio/mpeg',
                'mp3'	=>	array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
                'aif'	=>	array('audio/x-aiff', 'audio/aiff'),
                'aiff'	=>	array('audio/x-aiff', 'audio/aiff'),
                'aifc'	=>	'audio/x-aiff',
                'ram'	=>	'audio/x-pn-realaudio',
                'rm'	=>	'audio/x-pn-realaudio',
                'rpm'	=>	'audio/x-pn-realaudio-plugin',
                'ra'	=>	'audio/x-realaudio',
                'rv'	=>	'video/vnd.rn-realvideo',
                'wav'	=>	array('audio/x-wav', 'audio/wave', 'audio/wav'),
                'bmp'	=>	array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'),
                'gif'	=>	'image/gif',
                'jpeg'	=>	array('image/jpeg', 'image/pjpeg'),
                'jpg'	=>	array('image/jpeg', 'image/pjpeg'),
                'jpe'	=>	array('image/jpeg', 'image/pjpeg'),
                'png'	=>	array('image/png',  'image/x-png'),
                'tiff'	=>	'image/tiff',
                'tif'	=>	'image/tiff',
                'css'	=>	array('text/css', 'text/plain'),
                'html'	=>	array('text/html', 'text/plain'),
                'htm'	=>	array('text/html', 'text/plain'),
                'shtml'	=>	array('text/html', 'text/plain'),
                'txt'	=>	'text/plain',
                'text'	=>	'text/plain',
                'log'	=>	array('text/plain', 'text/x-log'),
                'rtx'	=>	'text/richtext',
                'rtf'	=>	'text/rtf',
                'xml'	=>	array('application/xml', 'text/xml', 'text/plain'),
                'xsl'	=>	array('application/xml', 'text/xsl', 'text/xml'),
                'mpeg'	=>	'video/mpeg',
                'mpg'	=>	'video/mpeg',
                'mpe'	=>	'video/mpeg',
                'qt'	=>	'video/quicktime',
                'mov'	=>	'video/quicktime',
                'avi'	=>	array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'),
                'movie'	=>	'video/x-sgi-movie',
                'doc'	=>	array('application/msword', 'application/vnd.ms-office'),
                'docx'	=>	array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'),
                'dot'	=>	array('application/msword', 'application/vnd.ms-office'),
                'dotx'	=>	array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'),
                'xlsx'	=>	array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'),
                'word'	=>	array('application/msword', 'application/octet-stream'),
                'xl'	=>	'application/excel',
                'eml'	=>	'message/rfc822',
                'json'  =>	array('application/json', 'text/json'),
                'pem'   =>	array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'),
                'p10'   =>	array('application/x-pkcs10', 'application/pkcs10'),
                'p12'   =>	'application/x-pkcs12',
                'p7a'   =>	'application/x-pkcs7-signature',
                'p7c'   =>	array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
                'p7m'   =>	array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
                'p7r'   =>	'application/x-pkcs7-certreqresp',
                'p7s'   =>	'application/pkcs7-signature',
                'crt'   =>	array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'),
                'crl'   =>	array('application/pkix-crl', 'application/pkcs-crl'),
                'der'   =>	'application/x-x509-ca-cert',
                'kdb'   =>	'application/octet-stream',
                'pgp'   =>	'application/pgp',
                'gpg'   =>	'application/gpg-keys',
                'sst'   =>	'application/octet-stream',
                'csr'   =>	'application/octet-stream',
                'rsa'   =>	'application/x-pkcs7',
                'cer'   =>	array('application/pkix-cert', 'application/x-x509-ca-cert'),
                '3g2'   =>	'video/3gpp2',
                '3gp'   =>	array('video/3gp', 'video/3gpp'),
                'mp4'   =>	'video/mp4',
                'm4a'   =>	'audio/x-m4a',
                'f4v'   =>	'video/mp4',
                'webm'	=>	'video/webm',
                'aac'   =>	'audio/x-acc',
                'm4u'   =>	'application/vnd.mpegurl',
                'm3u'   =>	'text/plain',
                'xspf'  =>	'application/xspf+xml',
                'vlc'   =>	'application/videolan',
                'wmv'   =>	array('video/x-ms-wmv', 'video/x-ms-asf'),
                'au'    =>	'audio/x-au',
                'ac3'   =>	'audio/ac3',
                'flac'  =>	'audio/x-flac',
                'ogg'   =>	'audio/ogg',
                'kmz'	=>	array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'),
                'kml'	=>	array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'),
                'ics'	=>	'text/calendar',
                'ical'	=>	'text/calendar',
                'zsh'	=>	'text/x-scriptzsh',
                '7zip'	=>	array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'),
                'cdr'	=>	array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'),
                'wma'	=>	array('audio/x-ms-wma', 'video/x-ms-asf'),
                'jar'	=>	array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'),
                'svg'	=>	array('image/svg+xml', 'application/xml', 'text/xml'),
                'vcf'	=>	'text/x-vcard',
                'srt'	=>	array('text/srt', 'text/plain'),
                'vtt'	=>	array('text/vtt', 'text/plain'),
                'ico'	=>	array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon')
            );
        }

        return $_mimes;
    }
}

调用

public function down(){
	$down = new ForceDownload();
	$down->force_download('uploads/xx.pdf',NULL,TRUE);
}

ThinkPHP 5 使用方法

放到 extend/download/ 文件夹下,即 extend/download/ForceDownload.php

实例化 $down = new \download\ForceDownload();

调用  $down->force_download(‘uploads/xx.pdf’,NULL,TRUE);

安装 PHP memcache memcached

安装 memcached

yum install memcached

需要 libevent 库,如未装则运行如下

yum install libevent libevent-devel

安装 php memcache 扩展

PHP memcache

http://pecl.php.net/package/memcache

PHP memcached

http://pecl.php.net/package/memcached
wget http://pecl.php.net/get/memcache-3.0.8.tgz
tar zxvf memcache-3.0.8.tgz
cd memcache-3.0.8
/usr/local/php5/bin/phpize
./configure --with-php-config=/usr/local/php5/bin/php-config
make
make install

php.ini 中加入扩展 extension=memcache.so

vim /usr/local/php5/lib/php.ini

重启 php-fpm,查看 phpinfo 

开机启动 (更改端口号如 11811)(如果使用 yum 方式安装,默认自启动)

vim /etc/sysconfig/memcached
PORT="11811"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""

编译方式安装的,在 /etc/rc.d/rc.local 中加入 (先 which memcached)

/usr/local/bin/memcached -u www -d -p 11811 -P /tmp/memcached.pid

或者创建 /etc/init.d/memcached

#!/bin/sh 
# 
# memcached:    MemCached Daemon 
# 
# chkconfig:    - 90 25
# description:  MemCached Daemon 
# 
# Source function library.
. /etc/rc.d/init.d/functions 
. /etc/sysconfig/network 
#[ ${NETWORKING} = "no" ] && exit 0
#[ -r /etc/sysconfig/dund ] || exit 0
#. /etc/sysconfig/dund 
#[ -z "$DUNDARGS" ] && exit 0
MEMCACHED="/usr/bin/memcached"
SERVER_IP="127.0.0.1"
SERVER_PORT="11811"
[ -f $MEMCACHED ] || exit 1
start() 
{ 
        echo -n $"Starting memcached: "
        daemon $MEMCACHED -u daemon -d -m 2048 -l $SERVER_IP -p $SERVER_PORT -P /tmp/memcached.pid
        echo 
} 
stop() 
{ 
        echo -n $"Shutting down memcached: "
        killproc memcached 
        echo 
}
  
# See how we were called. 
case "$1" in 
  start) 
        start 
        ;; 
  stop) 
        stop 
        ;; 
  restart) 
        stop 
        sleep 3
        start 
        ;; 
    *) 
        echo $"Usage: $0 {start|stop|restart}"
        exit 1
esac 
exit 0
#  chmod 755 /etc/init.d/memcached
#  chkconfig --add memcached
#  chkconfig memcached on
#  service memcached start
#  chkconfig --list memcached  #查看是否设置成功

启动

memcached -u root -d -p 11811

MacOS 自带 PHP 执行 php-fpm 的问题及解决

MacOS 下执行 php-fpm 会报错

ERROR: failed to open configuration file '/private/etc/php-fpm.conf': No such file or directory (2)
ERROR: failed to load configuration file '/private/etc/php-fpm.conf'
ERROR: FPM initialization failed

不能打开配置文件,因为没有 php-fpm.conf 文件,复制 php-fpm.conf.default 文件,改名为 php-fpm.conf,然后再根据需要改动配置。

cp /private/etc/php-fpm.conf.default /private/etc/php-fpm.conf

在此执行 php-fpm

WARNING: Nothing matches the include pattern '/private/etc/php-fpm.d/*.conf' from /private/etc/php-fpm.conf at line 125.
ERROR: failed to open error_log (/usr/var/log/php-fpm.log): No such file or directory (2)
ERROR: failed to post process the configuration
ERROR: FPM initialization failed

WARNING 找不到配置文件夹

cd /private/etc/php-fpm.d 
sudo cp www.conf.default www.conf

ERROR 不能打开错误日志文件。因为没有这个目录,配置到 /usr/local/var/log 目录。

vim /private/etc/php-fpm.conf,将 error_log 配置为 /usr/local/var/log/php-fpm.log

再次执行 php-fpm 依然报错

NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root

sudo php-fpm,再次报错:

ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (48)
ERROR: FPM initialization failed

编辑 www.conf,修改 listen 为 127.0.0.1:9999。

sudo vim /private/etc/php-fpm.d/www.conf

最后再次开启

开启php-fpm: sudo php-fpm -D

nginx 使用 php-fpm

nginx 配置文件

vim /usr/local/etc/nginx/nginx.conf
server {
    listen       8080;
    server_name  localhost;

    location / {
        root   /Users/guofeng/wwwroot/thinkphp/public;
        index  index.html index.htm index.php;
    }
    location ~ \.php$ {
        root /Users/guofeng/wwwroot/thinkphp/public;
        fastcgi_pass   127.0.0.1:9999;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}