PHP的输出缓冲区什么是输出缓冲区？PHP的输出流包含很多字节，通常都是程序员要PHP输出的文本，这些文本大多是echo语句或者printf()函数输出的。对于PHP中的输出缓冲区，你要知道三点内容。第一点是任何会输出点什么东西的函数都会用到输出缓冲区，当然这说的是用PHP写的程序。如果你是编写PHP扩展，你使用的函数（C函数）可能会直接将输出写到SAPI缓冲区层，而不需要经过OB层。你可以在源文件main/php_output.h中了解到这些C函数的API文档，这个文件给我们提供了很多其他的信息，例如默认的缓冲区大小。第二点你需要知道的是输出缓冲区层不是唯一用于缓冲输出的层，它实际上只是很多层中的一个。最后一点你要记住输出缓冲区层的行为跟你使用的SAPI（web或cli）相关，不同的SAPI可能有不同的行为。我们先通过一个图片来看看这些层的关系：上面这张图片展示了PHP中的三种缓冲区层的逻辑关系。上面的两层就是我们通常所认识到的“输出缓冲区”，最后一个是SAPI中的输出缓冲区。这些都是PHP中的层，当输出的字节离开PHP进入计算机体系结构中的更底层时，缓冲区又会不断出现（终端缓冲区（terminal buffer），fast-cgi缓冲区，web服务器缓冲区，OS缓冲区，TCP/IP栈缓冲区。。。）。请记住一个通用原则，除了这篇文章中讨论的PHP中的情况外，一个软件的很多部分都会先保留信息，然后再把它们传递到下一部分，直到最终把这些信息传递给用户。CLI的SAPI有点特殊，这里重点讲一下。CLI会将INI配置中的output_buffer选项强制设置为0，这表示禁用默认PHP输出缓冲区。所以在CLI中，默认情况下你要输出的东西会直接传递到SAPI层，除非你手动调用ob_()类函数。并且在CLI中，implicit_flush的值也会被设置为1。我们经常会搞不清implicit_flush的作用，当implicit_flush被设置为打开（值为1），一旦有任何输出写入到SAPI缓冲区层，它都会立即刷新（flush，意思是把这些数据写入到更低层，并且缓冲区会被清空）。换句话说就是：任何时候当你写入任何数据到CLI SAPI中时，CLI SAPI都会立即将这些数据扔到它的下一层去，一般会是标准输出管道，write()和fflush()这两个函数就是负责干这个事情的。简单，对吧！默认PHP输出缓冲区如果你使用不同于CLI的SAPI，像PHP-FPM，你会用到下面三个跟缓冲区相关的INI配置选项：output_bufferingimplicit_flushoutput_handler在搞清楚这几个选项的含义之前，有一点需要先说明下，不能在运行时使用ini_set()改这几个选项的值。这些选项的值会在PHP程序启动的时候，还没有运行任何脚本之前解析，所以也许在运行时可以使用ini_set()改变它们的值，但改变后的值并不会生效，一切都已经太迟了，因为输出缓冲区层已经启动并已激活。你只能通过编辑php.ini文件或者是在执行PHP程序的时候使用-d选项才能改变它们的值。默认情况下，PHP发行版会在php.ini中把output_buffering设置为4096个字节。如果你不使用任何php.ini文件（或者也不会在启动PHP的时候使用-d选项），它的默认值将为0，这表示禁用输出缓冲区。如果你将它的值设置为“ON”，那么默认的输出缓冲区的大小将是16kb。你可能已经猜到了，在web应用环境中对输出的内容使用缓冲区对性能有好处。默认的4k的设置是一个合适的值，这意味着你可以先写入4096个ASCII字符，然后再跟下面的SAPI层通信。并且在web应用环境中，通过socket一个字节一个字节的传输消息的方式对性能并不好。更好的方式是把所有内容一次性传输给服务器，或者至少是一块一块地传输。层与层之间的数据交换的次数越少，性能越好。你应该总是保持输出缓冲区处于可用状态，PHP会负责在请求结束后把它们中的内容传输给终端用户，你不用做任何事情。implicit_flush已在前面谈论CLI的时候提到过。对于其他的SAPI，implicit_flush默认被设置为关闭(off)，这是正确的设置，因为只要有新数据写入就刷新SAPI的做法很可能并非你所希望的。对于FastCGI协议，刷新操作(flushing)是每次写入后都发送一个FastCGI数组包(packet)，如果发送数据包之前先把FastCGI的缓冲区写满会更好一些。如果你想手动刷新SAPI的缓冲区，使用PHP的flush()函数。如果你想写一次就刷新一次，你可以设置INI配置中的implicit_flush选项，或者调用一次ob_implicit_flush()函数。output_handler是一个回调函数，它可以在缓冲区刷新之前修改缓冲区中的内容。PHP的扩展提供了很多回调函数（用户也可以自己编写回调函数，下面会讲到）。ob_gzhandler : 使用ext/zlib压缩输出mb_output_handler : 使用ext/mbstring转换字符编码ob_iconv_handler : 使用ext/iconv转换字符编码ob_tidyhandler : 使用ext/tidy整理输出的HTML文本ob_[inflate/deflate]_handler : 使用ext/http压缩输出ob_etaghandler : 使用ext/http自动生成HTTP的Etag缓冲区中的内容会传递给你选择的回调函数（只能用一个）来执行内容转换的工作，所以如果你想获取PHP传输给web服务器以及用户的内容，你可以使用输出缓冲区回调。当前有一点也需要提一下，这里说的“输出”指的是消息头（headers）和消息体（body）。HTTP的消息头也是OB层的一部分。消息头和消息体当你使用一个输出缓冲区（无论是用户的，还是PHP的）的时候，你可能想以你希望的方式发送HTTP消息头和内容。你知道任何协议都必须在发送消息体之前发送消息头（这也是为什么叫做“头”），但是如果你使用了输出缓冲区层，那么PHP会接管这些，而不需要你操心。实际上，任何跟消息头的输出有关的PHP函数（header()，setcookie()，session_start()）都使用了内部的sapi_header_op()函数，这个函数只会把内容写入到消息头缓冲区中。然后当你输出内容是，例如使用printf()，这些内容会写入到输出缓冲区（假设只有一个）。当这个输出缓冲区中的内容需要被发送时，PHP会先发送消息头，然后发送消息体。PHP为你搞定了所有的事情。如果你觉得不爽，想自己动手，那你就只有把输出缓冲区禁用掉，除此之外别无他法。用户输出缓冲区（user output buffers)对于用户输出缓冲区，我们先通过一个示例来看看它是怎么工作的，以及你可以用它来做什么。再强调一下，如果你想使用默认PHP输出缓冲区层的话，你不能使用CLI，因为它已禁用了这个层。下面的这个示例用的就是默认PHP输出缓冲区，使用了PHP的内部web服务器SAPI：/* launched via php -doutput_buffering=32 -dimplicit_flush=1 -S127.0.0.1:8080 -t/var/www */ echo str_repeat('a', 31); sleep(3); echo 'b'; sleep(3); echo 'c';在这个示例中，启动PHP的时候将默认输出缓冲区的大小设置为32字节，程序运行后会先向其中写入31个字节，然后进入睡眠状态。此时屏幕是空的，什么都不会输出，跟预计一样。2秒之后睡眠结束，再写入了一个字节，这个字节填满了缓冲区，它会立即刷新自身，把里面的数据传递给SAPI层的缓冲区，因为我们将implicit_flush设置为1，所以SAPI层的缓冲区也会立即刷新到下一层。字符串’aaaaaaaaaa{31个a}b’会出现在屏幕上，然后脚本再次进入睡眠状态。2秒之后，再输出一个字节，此时缓冲区中有31个空字节，但是PHP脚本已执行完毕，所以包含这1个字节的缓冲区也会立即刷新，从而会在屏幕上输出字符串’c’。从这个示例我们可以看到默认PHP输出缓冲区是如何工作的。我们没有调用任何跟缓冲区相关的函数，但这并不意味这它不存在，你要认识到它就存在当前程序的运行环境中（在非CLI模式中才有效）。OK，现在开始讨论用户输出缓冲区，它通过调用ob_start()创建，我们可以创建很多这种缓冲区（至到内存耗尽为止），这些缓冲区组成一个堆栈结构，每个新建缓冲区都会堆叠到之前的缓冲区上，每当它被填满或者溢出，都会执行刷新操作，然后把其中的数据传递给下一个缓冲区。ob_start(function($ctc) { static $a = 0; return $a++ . '- ' . $ctc . "\n";}, 10); ob_start(function($ctc) { return ucfirst($ctc); }, 3); echo "fo"; sleep(2); echo 'o'; sleep(2); echo "barbazz"; sleep(2); echo "hello"; /* 0- FooBarbazz\n 1- Hello\n */在此我代替原作者讲解下这个示例。我们假设第一个ob_start创建的用户缓冲区为缓冲区1，第二个ob_start创建的为缓冲区2。按照栈的后进先出原则，任何输出都会先存放到缓冲区2中。缓冲区2的大小为3个字节，所以第一个echo语句输出的字符串'fo'（2个字节）会先存放在缓冲区2中，还差一个字符，当第二echo语句输出的'o'后，缓冲区2满了，所以它会刷新(flush)，在刷新之前会先调用ob_start()的回调函数，这个函数会将缓冲区内的字符串的首字母转换为大写，所以输出为'Foo'。然后它会被保存在缓冲区1中，缓冲区1的大小为10。第三个echo语句会输出'barbazz'，它还是会先放到缓冲区2中，这个字符串有7个字节，缓冲区2已经溢出了，所以它会立即刷新，调用回调函数得到的结果为'Barbazz'，然后被传递到缓冲区1中。这个时候缓冲区1中保存了'FooBarbazz'，10个字符，缓冲区1会刷新，同样的先会调用ob_start()的回调函数，缓冲区1的回调函数会在字符串前面添加行号，以及在尾部添加一个回车符，所以输出的第一行是'o- FooBarbazz'。最后一个echo语句输出了字符串'hello'，它大于3个字符，所以会触发缓冲区2刷新，因为此时脚本已执行完毕，所以也会立即刷新缓冲区1，最终得到的第二行输出为'1- Hello'。应用大文件流式下载<?php header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="test.txt"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); $file = 'a big file'; $fp = fopen('php://output', 'wb+'); $fe = fopen($file, 'rb'); ob_implicit_flush(); while (!feof($fe)) { fwrite($fp, fread($fe, 2048)); ob_flush(); flush(); } fclose($fe); fclose($fp);总结输出层（output layer）就像一个网，它会把所有从PHP”遗漏“的输出圈起来，然后把它们保存到一个大小固定的缓冲区中。当缓冲区被填满了的时，里面的内容会刷新（写入）到下一层（如果有的话），或者是写入到下面的逻辑层：SAPI缓冲区。开发人员可以控制缓冲区的数量、大小以及在每个缓冲区层可以执行的操作（清除、刷新和删除）。这种方式非常灵活，它允许库和框架设计者可以完全控制它们自己输出的内容，并把它们放到一个全局的缓冲区中。对于输出，我们需要知道任何输出流的内容和任何HTTP消息头，PHP都会以正确的顺序发送它们。输出缓冲区也有一个默认缓冲区，可以通过设置3个INI配置选项来控制它，它们是为了防止出现过大量的细小的写入操作，从而造成访问SAPI层过于频繁，这样网络消耗会很大，不利于性能。PHP的扩展也可以定义回调函数，然后在每个缓冲区上执行这个回调，这种应用已经有很多了，例如执行数据压缩，HTTP消息头管理以及搞很多其他的事情。转载自 https://gywbd.github.io/posts/2015/1/php-output-buffer-in-deep.html
PHP安全基础一生产环境php.ini推荐配置; 基础设置 ; 关闭错误输出 display_erros = Off ; 错误日志输出到指定位置 error_log = /var/log/error.log ; 显示除通知和编码标准警告之外的所有错误。 error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED ; 关闭php版本号在http头中的显示 expose_php = Off ; 限制php访问的文件系统位置；如果设置的是一个指定目录，则需要在最后加上 '/'，否则会被认为是目录的前缀 open_basedir = /home/www/ ; 禁用远程文件访问 allow_url_fopen = Off ; 禁用远程文件包含 allow_url_include = Off ; 禁用危险函数 危险函数 参考附录中的危险函数 disable_functions = phpinfo,eval ; cookie安全 ; 开启httponly 让Cookie在浏览器中不可见，浏览器脚本语言(如JavaScript)无法访问它 session.cookie_httponly = 1 ; 如果开启了ssl 则设置此选项，只有https下请求才会携带cookies session.cookie_secure = 1代码安全会话相关setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); /** name Cookie 名称。 value Cookie 值。 这个值储存于用户的电脑里，请勿储存敏感信息。 比如 name 是 'cookiename'， 可通过 $_COOKIE['cookiename'] 获取它的值。 expire Cookie 的过期时间。 这是个 Unix 时间戳，即 Unix 纪元以来（格林威治时间 1970 年 1 月 1 日 00:00:00）的秒数。 也就是说，基本可以用 time() 函数的结果加上希望过期的秒数。 或者也可以用 mktime()。 time()+60*60*24*30 就是设置 Cookie 30 天后过期。 如果设置成零，或者忽略参数， Cookie 会在会话结束时过期（也就是关掉浏览器时）。 Note: 你可能注意到了，expire 使用 Unix 时间戳而非 Wdy, DD-Mon-YYYY HH:MM:SS GMT 这样的日期格式，是因为 PHP 内部作了转换。 path Cookie 有效的服务器路径。 设置成 '/' 时，Cookie 对整个域名 domain 有效。 如果设置成 '/foo/'， Cookie 仅仅对 domain 中 /foo/ 目录及其子目录有效（比如 /foo/bar/）。 默认值是设置 Cookie 时的当前目录。 domain Cookie 的有效域名/子域名。 设置成子域名（例如 'www.example.com'），会使 Cookie 对这个子域名和它的三级域名有效（例如 w2.www.example.com）。 要让 Cookie 对整个域名有效（包括它的全部子域名），只要设置成域名就可以了（这个例子里是 'example.com'）。 旧版浏览器仍然在使用废弃的 » RFC 2109， 需要一个前置的点 . 来匹配所有子域名。 secure 设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。 设置成 TRUE 时，只有安全连接存在时才会设置 Cookie。 如果是在服务器端处理这个需求，程序员需要仅仅在安全连接上发送此类 Cookie （通过 $_SERVER["HTTPS"] 判断）。 httponly 设置成 TRUE，Cookie 仅可通过 HTTP 协议访问。 这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。 要有效减少 XSS 攻击时的身份窃取行为，可建议用此设置（虽然不是所有浏览器都支持），不过这个说法经常有争议。 PHP 5.2.0 中添加。 TRUE 或 FALSE **/php版本// 使用php7版本 更少的漏洞 // 开启严格模式，严格约束变量类型，防止数据类型转换造成的安全隐患 declare(strict_types=1); // 使用php7中的random_int,random_bytes代替php5中的mt_rand random_int(100, 900); bin2hex(random_bytes(10)); // 尽量减少非必要模块加载 // 使用第三方安全扩展 如 Suhosin, Taint 附录PHP中的危险函数函数名函数功能危害chgrp()改变文件或目录所属用户组高chown()改变文件或目录的所有者高chroot()改变当前PHP进程的工作根目录，仅支持linux且cli模式高dl()在PHP运行过程中，加载一个PHP外部模块高exec()允许执行一个外部程序(Unix Shell 或 CMD命令等)高ini_alter()init_set()别名高ini_restore()将PHP环境配置参数恢复为初始值高ini_set()修改、设置PHP环境配置参数高passthru()允许执行一个外部程序并回显输出，类似exec()高pfsockopen()建立一个Internet或UNIX域的socket持久连接高phpinfo()输出PHP环境信息、扩展、web环境信息等高popen()可通过popen()参数传递命令，并对popen()打开的文件进行执行高proc_get_status()获取是使用proc_open()所打开进程的信息高proc_open()执行一个命令并打开文件指针用于读取及写入高readlink()返回符号连接指向的目标文件内容中scandir()列出指定路径中的文件和目录中shell_exec()通过shell执行命令，并将执行结果作为字符串返回高stream_socket_server()建立一个Internet或UNIX服务器连接中symlink()对已有的target建立一个名为link的符号连接高syslog()调用UNIX系统层syslog()函数中system()允许执行一个外部程序并回显输出，类似passthru()高
php在apache服务器下运行方式主要有一下几种：模块化(效率最高)CGI方式(不推荐，效率低)FastCgiphpfpm1. 模块化方式在编译安装php的时候,增加--with-apxs2=/server/httpd/bin/apxs 选项，会自动生成php5_module。在http.conf文件中如下设置 # 加载模块 LoadModule php5_module modules/libphp5.so # 设置方式1 <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> # 设置方式2 # 在<IfModule mime_module>中添加如下内容 AddType application/x-httpd-php .php 2.CGI方式CGI是通用网关接口协议的缩写，是一种通用的规范协议，与语言无关，编译安装的php在bin下会存在一个php-cgi，就是php自带的CGI接口程序设置如下# 加载模块 LoadModule alias_module modules/mod_alias.so LoadModule cgid_module modules/mod_cgid.so(linux) LoadModule cgi_module modules/mod_cgi.so(windows) LoadModule actions_module modules/mod_actions.so # 在安装好的php目录下的bin下复制php-cgi到 /server/www/cgi-bin # /server/www/cgi-bin 此目录是在安装apache的时候自动生成的，/server/www/是apaceh服务器的网页根目录 # 将安装好的php-cgi复制到有执行CGI程序权限的目录下 # 这个目录可以是任意目录，只要在配置中给权限就好，建议放在官方推荐的位置，根据安装位置的不同，默认的位置不同 cp /server/php56/bin/php-cgi /server/www/cgi-bin/ # 在http.conf文件中查找ScriptAlias，规定了CGI执行目录 ScriptAlias /cgi-bin/ "/server/www/cgi-bin" <Directory "/server/www/cgi-bin"> AllowOverride None Options All Require all granted </Directory> AddType application/x-httpd-php .php Action application/x-httpd-php /cgi-bin/php-cgi # application/x-httpd-php 可以自定义 扩展.php的Mime 3.FastCgi方式FastCgi是对CGI方式的一个优化，效率有显著提升php官网中的FastCgi安装说明 点我不过FastCgi的官网已经倒闭了....好在Apache提供了新的模块mod_fcgid来支持FastCgi的实现mod_fcgid官方文档地址 点我# 安装 mod_fcgid 模块 wget http://mirror.bit.edu.cn/apache//httpd/mod_fcgid/mod_fcgid-2.3.9.tar.gz tar -zxvf mod_fcgid-2.3.9.tar.gz cd mod_fcgid-2.3.9 APXS=/server/httpd/bin/apxs ./configure.apxs make make install 查看http.conf文件，会发现配置文件LoadModule最后面会自动加了一行 LoadModule fcgid_module modules/mod_fcgid.so # 这里是通用设置所有的.php文件都会被处理 # 不同的虚拟机还可以配置不同的php版本处理 <IfModule fcgid_module> # 初始化设置 # CGI进程的最大请求个数 FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 1000 #fcgi每个进程的最大请求数要<= 上面的PHP_FCGI_MAX_REQUESTS 否则会出现请求完不成的问题 FcgidMaxRequestsPerProcess 1000 #php-cgi最大的进程数 FcgidMaxProcesses 5 #最大执行时间 FcgidIOTimeout 120 FcgidIdleTimeout 120 AddHandler fcgid-script .php <FilesMatch "\.php$"> Options ExecCgi FcgidWrapper /server/www/cgi-bin/php-cgi .php </FilesMatch> </IfModule> # 为虚拟机设置不同的php版本 # 注释掉上文中的FilesMatch容器 # 在虚拟机内添加如下设置 # 更改不同版本的cgi路径即可 <FilesMatch '\.php$'> Options ExecCgi FcgidWrapper /server/www/cgi-bin/php-cgi .php </FilesMatch> 4. php-fpm php fastcgi process manager该方式的本质还是FastCgi不过管理Cgi的工作由Apache变成了php，Apache只做转发工作该方式需要在编译安装的时候开启 --enable-fpm安装成功在安装目录下的sbin下会出现一个php-fpmphp-fpm方式 # 复制启动脚本到 启动目录 cp /server/source/php-5.6.38/sapi/fpm/init.d.php-fpm.in /etc/init.d/php-fpm56 # 复制配置文件到/etc下 # 默认的文件在安装路径下的etc中 cp /server/php56/etc/php-fpm.conf.default /etc/php-fpm56.conf # 修改php-fpm56.conf配置文件 默认参数基本不需要修改什么php-fpm调优参数设置参考 这里这里附上一份宝塔面板的php-fpm参数配置供参考[global] pid = /www/server/php/56/var/run/php-fpm.pid error_log = /www/server/php/56/var/log/php-fpm.log log_level = notice [www] listen = /tmp/php-cgi-56.sock listen.backlog = -1 listen.allowed_clients = 127.0.0.1 listen.owner = www listen.group = www listen.mode = 0666 user = www group = www pm = dynamic pm.status_path = /phpfpm_56_status pm.max_children = 80 pm.start_servers = 15 pm.min_spare_servers = 15 pm.max_spare_servers = 80 request_terminate_timeout = 100 request_slowlog_timeout = 30 slowlog = var/log/slow.log # 启动php-fpm /etc/init.d/php-fpm56 start # 修改http.conf文件 # 需要代理模块 LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so ProxyPass '/status' fcgi://127.0.0.1:9000 # 这个是设置访问/status 查看当前php-fpm的工作情况 实际生产环境中 需要把这个屏蔽掉 ProxyRequests Off ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/server/www/htdocs/p5/$1 # 这里的目录要和访问的文件实际所在路径完全一致 相关文章apache安装看 这里apache配置看 这里
Apache安装参看此文章 https://xbug.top/index.php/archives/195.html基础命令# 启动服务 /server/httpd/bin/apachectl -k start # 立即停止 kill -TERM `cat /server/httpd/logs/httpd.pid` # 立即停止2 /server/httpd/bin/apachectl -k stop # 优雅重启 # 此方式重启不会停止服务 # 在重启过程中确保有适当数量的进程和线程以响应客户端的请求 /server/httpd/bin/apachectl -k graceful # 立即重启 /server/httpd/bin/apachectl -k restart # 优雅停止 # 进程会完成现有的服务再退出，如果没有服务，立刻退出 /server/httpd/bin/apachectl -k graceful-stop # 检测配置文件语法错误 /server/httpd/bin/apachectl -t 配置文件详解主配置文件httpd.conf详解# 常用配置及配置详解 # apache安目录，编译时指定，不指定路径时默认路径为/usr/local/apache2 ServerRoot "/server/httpd" # 主站监听端口，可以监听多个端口 #Listen 12.34.56.78:80 # Listen 443 Listen 80 # 模块动态加载，这里只列举几个用到的模块 # 别名 LoadModule alias_module modules/mod_alias.so # url重写 LoadModule rewrite_module modules/mod_rewrite.so # php以模块的形式处理请求 LoadModule php5_module modules/libphp5.so # <Ifxxxx > 容器下文与详细说明 <IfModule unixd_module> # 运行httod服务的用户 User www # 运行httod服务的用户组 Group www </IfModule> # 管理员邮件地址 ServerAdmin you@example.com # 出错时是否显示服务器信息 ServerSignature On # On显示 # Off不显示,默认Off # Email,On的升级版，显示且点击ServerName就会向ServerAdmin中设置的邮箱发邮件 #显示的内容如下 # Apache/2.4.38 (Unix) PHP/5.6.38 Server at 192.168.73.129 Port 80 # 控制Response Header中的Server显示 ServerTokens Full # 选项有 Major | Minor | Min[imal] | Prod[uctOnly] | OS | Full # 默认是Full 这里的选项也会影响ServerSignature的显示内容，主要是详细的服务器版本号内容 # 主站点名称，域名或者IP皆可 ServerName 127.0.0.1:80 # 保持长连接设置 KeepAlive On # 一个连接服务最多请求次数 MaxKeepAliveRequests 100 # 长连接持续时间,超过该时间没有请求数据则断开连接 KeepAliveTimeOut 15 # 记录父进程PID的文件,默认值如下 PidFile "logs/httpd.pid" # 常用的资源限制配置,可减轻DOS攻击 # 设置客户端发送的HTTP请求的最大字节数 默认0 不限制 LimitRequestBody 0 # 限制为500K # LimitRequestBody 512000 # 设置客户端向服务器请求中HTTP请求头域的数量 LimitRequestFields 100 # 默认值一般为100 # 设置客户端发送的HTTP请求头的最大字节数 一般不要改动 LimitRequestFieldsize 8190 # 设置客户端发送的HTTP请求行的最大字节数 # GET / HTTP/1.1 LimitRequestLine 8190 # Dirctory容器对根目录的限制 <Directory /> # indexs 没有默认文件的情况下展示目录结构 options更多选项下文详细叙述 options indexes # 禁用.htaccess文件 AllowOverride none Require all denied </Directory> # 主站访问的根目录 DocumentRoot "/server/www/htdocs" # 对根目录的限制 <Directory "/server/www/htdocs"> # indexes允许显示文件目录 FollowSymLinks 允许文件系统使用符号连接 Options FollowSymLinks indexes # 允许使用.htacess文件 AllowOverride All Require all granted </Directory> <IfModule dir_module> # 设置默认访问文件，顺序为从左到右 DirectoryIndex index.php index.html </IfModule> # 拒绝用户访问.ht开头的文件(.htaccess) <Files ".ht*"> Require all denied </Files> # 匹配.php后缀文件，使用php处理器处理该文件 <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> # 错误日志配置 未指定的目录都是相对于ServerRoot ErrorLog "logs/error_log" # 日志级别 LogLevel warn <IfDefine tes1> Redirect / http://www.baidu.com/ </IfDefine> # 日志格式 <IfModule log_config_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common <IfModule logio_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> # 访问日志 CustomLog "logs/access_log" common </IfModule> <IfModule alias_module> ScriptAlias /cgi-bin/ "/server/www/cgi-bin/" </IfModule> <IfModule cgid_module> </IfModule> <Directory "/server/www/cgi-bin"> AllowOverride None Options None Require all granted </Directory> <IfModule headers_module> RequestHeader unset Proxy early </IfModule> <IfModule mime_module> # 设置mime.types文件的位置，此文件规定了apache识别的文件后缀 TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz </IfModule> <IfModule proxy_html_module> Include conf/extra/proxy-html.conf </IfModule> <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> 容器详解分两种基本类型1. 启动时生效的容器<IfDefine> # 此容器只在启动时添加了-D参数才会生效 # 配置 <IfDefine test> # 这里的test和-D参数指定的一致 否则不起作用 Redirect / http://www.baidu.com/ </IfDefine> # 使用如下命令启动服务 /server/httpd/bin/apachectl -k start -D test # 访问根域名的请求就会被转发到百度 <IfModule> # 该容器代表xxx模块被装载了 才会起作用 # 不装载对应模块 配置文件也不会报错 <IfModule proxy_html_module> Include conf/extra/proxy-html.conf </IfModule> <IfVersion> # 判断服务器版本的容器 <IfVersion >= 2.1> # 仅在版本高于 2.1.0 的时候才生效 </IfVersion>2.常规容器(配置段)，一般都是针对各种请求常规容器的配置语法基本相同，主要有以下几项：Options选项 规定当前配置段可使用的特性语法:Options: None|All|[[+|-]Indexes][FllowSymLinks][Includes][SymLinksifOwnerMatch][ExecCGI][MultiViews] 参数:None: 不启用任何额外特性;All: 除 MultiViews 之外的所有特性。这也是Options指令的 默认设置;Indexes:如果输入的网址对应服务器上的一个文件目录，而此目录中又没有 DirectoryIndex指令(例如： DirectoryIndex index.html index.php)，那么服务器会返回目录列表;FllowSymLinks:服务器允许在此目录中使用符号连接(简单来说就是ln -s 创建的链接文件是否可用)。如果该配置选项位于 <Location>配置段中，将会被忽略;MultiViews:允许使用多重视图(基本用不到);SymLinksIfOwnerMatch:服务器仅在符号连接与目标文件或目录的所有者具有相同的用户ID时才使用它。简而言之，只有当符号连接和符号连接指向的目标文件或目录的所有者是同一用户时，才会使用符号连接。该选项需要开启FllowSymLinks前置；如果该配置选项位于 <Location>配置段中，将会被忽略;ExecCGI:允许使用 mod_cgi模块执行CGI脚本;Includes:允许使用 mod_include模块提供的服务器端包含功能。IncludesNOEXEC:允许服务器端包含，但禁用"#exec cmd"和"#exec cgi"。但仍可以从ScriptAlias目录使用"#include virtual"虚拟CGI脚本。备注参数中+-的含义Apache允许在一个目录配置中设置多个Options指令,Options选项存在继承关系。一般来说，如果一个目录被多次设置了Options，则指定特性数量最多的一个Options指令会被完全接受(其它的被忽略)，而各个Options指令之间并不会合并。但是如果我们在可选配置项前加上了符号"+"或"-"，那么表示该可选项将会被合并。所有前面加有"+"号的可选项将强制覆盖当前的可选项设置，而所有前面有"-"号的可选项将强制从当前可选项设置中去除。混合使用前面带"+"/"-"和前面不带"+"/"-"的同一可选项，可能会导致出现意料之外的结果。#示例1 <Directory /web/file> Options Indexes FollowSymLinks </Directory> <Directory /web/file/image> Options Includes </Directory> #目录/web/file/image只会被设置Includes特性 #示例2 <Directory /web/file> Options Indexes FollowSymLinks </Directory> <Directory /web/file/image> Options +Includes -Indexes </Directory> #目录/web/file/image将会被设置Includes、FollowSymLinks两种特性AllowOverride选项 规定.htaccess文件是否可用,可用哪些配置项语法:AllowOverride: None|All|AuthConfig|FileInfo|Indexes|Limit|Options参数:None: 禁止使用.htaccess(由AccessFileName决定名字)文件All: 可以使用.htaccess，且支持所有选项AuthConfig:允许使用与认证授权相关的指令(AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, 等)。FileInfo:允许使用控制文档类型的指令(DefaultType, ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, mod_mime中的 Add 和 Remove 指令等等)、控制文档元数据的指令(Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName)、mod_rewrite中的指令(RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule)和mod_actions中的Action指令。Indexes:允许使用控制目录索引的指令(AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, 等)。Limit:允许使用控制主机访问的指令(Allow, Deny, Order)。Options[=Option,...]:允许使用控制指定目录功能的指令(Options和XBitHack)。可以在等号后面附加一个逗号分隔的(无空格的)Options选项列表，用来控制允许Options指令使用哪些选项。Allow选项 规定允许访问的来源语法:Allow from All|ip地址|域名|其它 示例:Allow form all # 全部允许访问 Allow from a.com Allow from .net c.top # 域名方式的限制 Allow from 10.1 Allow from 192.168.1.1 192.168.1.2 # 支持部分IP地址、完整IP地址 # 其它特征控制 SetEnvIf User-Agent ^Mozilla/5\.0 let_me_in <Directory "/docroot"> Order Deny,Allow Deny from all Allow from env=let_me_in </Directory> # 只允许代理头为 Mozilla/5.0 的用户访问Deny选项 规定拒绝访问的来源语法:Deny from All|ip地址|域名|其它 # 完全同Allow一致 Order选项 控制默认访问状态语法:Order Allow,Deny # 或者 Order Deny,Allow参数：Allow,Deny:先匹配Allow的规则，再匹配Deny的规则，都匹配不上的请求默认拒绝。Deny,Allow:先匹配Deny的规则，再匹配Allow的规则，都匹配不上的请求默认允许。 2.4版本的授权方式 2.4版本的访问控制方式与2.2不同，兼容2.2的授权语句Order、Allow、Deny(不推荐使用此方式授权,未来的版本会不再提供支持)# 2.2版本 拒绝全部访问 Order Allow,Deny Deny from All # 2.4版本 Require all denied # 2.2版本 允许全部 Order Allow,Deny Allow from All # 2.4版本 Require all granted # 2.4版本常用 Require all granted #允许所有来源访问 Require all denied #拒绝所有来源访问 Require expr expression #允许表达式为true时访问 Require ip 10 172.20 192.168.2 #允许 特定IP段访问，多个段之前用空格隔开。每个段使用开头几项表示 #只允许来自域名splaybow.com的主机访问 Require host splaybow.com # 来自10.1.1.2的访问将被拒绝 Require not ip 10.1.1.2 # 只允许GET方法访问 Require method GET # 只允许代理为 Mozilla/5.0 的用户连接 SetEnvIf User-Agent ^Mozilla/5\.0 let_me_in <Directory "/server/www/htdocs/v1"> Require env let_me_in </Directory> # 授权容器(2.4新增)组合多条授权语句 # RequireAll 在此元素中包含的规则，拒绝优先执行 <RequireAll> Require all granted # 允许所有 Require not ip 192.168.1.1 # 拒绝指定ip下的访问 </RequireAll> # RequireAny 在此元素中包含的规则，允许优先执行 # 除Require All denied外，不能写其他否定规则(简单来说就是不能写not条件) <RequireAny> Require all denied Require ip 192.168.1.1 </RequireAny> # 不会用 会了在补上 <RequireNone> ... <RequireNone> 常规容器主要有文件系统、网络空间、其他，容器支持嵌套# 文件系统主要有一下几种<Directory>,<DirectoryMatch>,<Files>,<FilesMatch> <Directory '/a/b'> # 针对目录/a/b的设置 # 支持使用 Unix shell 风格匹配的通配符字符串 # ?匹配单个字符; * 匹配任意字符序列 # <Directory ~ '/^.*?/'> 可使用 ~ 设置正则(不建议，建议正则使用DirectoryMatch) <Directory> <DirectoryMatch "/.*img.*/"> # 针对正则匹配的设置 # 所有路径名中带img的 </DirectoryMatch> <Files ".htaccess"> # 匹配指定文件 # 支持使用 Unix shell 风格匹配的通配符字符串 # ~ 支持正则(不建议) </Files> <FilesMatch "/.*.txt/"> # 正则匹配 # 匹配所有的txt文件 </FilesMatch> #网络空间 # 匹配常规url <Location "/images"> </Location> # 正则匹配url <LocationMatch regex> </LocationMatch> # 代理部分在下面做基础说明 <Proxy> <ProxyMatch> # 虚拟主机容器 <VirtualHost> # 基本虚拟主机配置 <VirtualHost *:80> # xxx:8080 DocumentRoot "/www/vhost1" # 主目录 ServerName www.test.com # IP地址或域名 ServerAlias www.test1.cn #可省略 别名，也可通过别名访问 ServerAdmin stefan321@qq.com #可省略 网站管理员 ErrorLog logs/dev-error.log #可省略 错误日志 CustomLog logs/dev-access.log common #可省略 访问日志 ErrorDocument 404 logs/404.html #可省略 404错误页面 <Directory "/www/vhost1"> Options Indexes FollowSymLinks AllowOverride All Order Allow,Deny Allow from all RewriteEngine on # rewirte重写规则 也可以使用.htaccess RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] </Directory> </VirtualHost> 代理基本设置Apache官方文档使用代理功能需要加载代理模块基础代理模块 proxy_module代理模块与协议的对应关系ProtocolModuleAJP13 (Apache JServe Protocol version 1.3)mod_proxy_ajpCONNECT (for SSL)mod_proxy_connectFastCGImod_proxy_fcgiftpmod_proxy_ftpHTTP/0.9, HTTP/1.0, and HTTP/1.1mod_proxy_httpSCGImod_proxy_scgiWS and WSS (Web-sockets)mod_proxy_wstunnel一些简单的代理示例 注意 结尾的/一定要同步 # 将到/foo的请求转发到 后面的http 服务 ProxyPass "/foo" "http://foo.example.com/bar" ProxyPassReverse "/foo" "http://foo.example.com/bar" # 设置其它参数 ProxyPass "/test" "http://127.0.0.1" connectiontimeout=5 timeout=30 # 通过代理块设置限制 <Proxy "/test"> Require ip 192.168.0 </Proxy> # 不代理目标子目录 <Location "/mirror/foo/"> ProxyPass "http://backend.example.com/" </Location> <Location "/mirror/foo/i"> ProxyPass "!" </Location> # 等同如下 不可混用 ProxyPass "/mirror/foo/i" "!" ProxyPass "/mirror/foo" "http://backend.example.com" # 反向代理 负载均衡示例 <VirtualHost 192.168.73.129:80> # 虚拟机做负载均衡入口 DocumentRoot "/server/www/htdocs" # 静态资源目录 ServerName 192.168.73.129 Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <Proxy "balancer://mycluster"> BalancerMember "http://127.0.0.1:8080" route=1 BalancerMember "http://127.0.0.2:8080" route=2 # BalancerMember "http://127.0.0.3:8080" ProxySet stickysession=ROUTEID </Proxy> ProxyPass "/index/" "balancer://mycluster/" ProxyPassReverse "/index/" "balancer://mycluster/" <Location /bm> # 设置负载均衡查看器 SetHandler balancer-manager Require all granted ProxyPass ! </Location> </VirtualHost> 设置apache支持php文件解析apahce解析php文件有三种方式module、fastcgi、phpfpm,这里只说明模块化的方式将php编译为apache的一个模块# 加载模块 LoadModule php5_module modules/libphp5.so # 设置方式1 <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> # 设置方式2 # 在<IfModule mime_module>中添加如下内容 AddType application/x-httpd-php .phpCGI、FastCgi、php-fpm请参考这篇文章点我Apache文件解析可以看这篇文章 点我一些常用的特殊指令# Location LocationMatch ForceType image/gif # 强制设置HTTP Content-Type # 别名设置 Alias /download/ /root/download/ <Directory "/root/download"> ... </Directory> # 预留的带cgi执行权限的别名 ScriptAlias /cgi-bin/ /root/cgi/ # 将制定扩展的文件和处理程序绑定 AddHandler xxx .php # 与下面放的效果相同 <FilesMatch '/*.php$'> SetHandler xxx </FilesMatch> # 允许跨域访问 # 在VirtualHost或Directory中设置 Header set Access-Control-Allow-Origin "http://a.com" # 或者 "*"
安装前准备安装目录创建mkdir /server需要安装以下依赖yum install gcc yum install gcc-c++ yum install ncurses-devel yum install autoconf yum install expat-devel yum install zlib-devel yum install libxml2-devel yum install openssl yum install openssl-devel yum install curl-devel yum install libpng-devel yum install freetype-develcmake编译参数详情：https://blog.csdn.net/zero_295813128/article/details/51223209https://www.cnblogs.com/martinzhang/p/3455681.htmlMysql源码编译安装1. 资源获取下载地址：https://dev.mysql.com/downloads/mysql/版本区别：https://www.cnblogs.com/langtianya/p/5185601.html获取安装包：# cmake安装包获取 wget https://github.com/Kitware/CMake/releases/download/v3.14.2/cmake-3.14.2.tar.gz # boost安装包获取 # mysql5.7.5版本及以上需要boost，而且可能需要的boost版本还不一样，最好下载mysql源码的时候就下载带有boost的 #wget https://dl.bintray.com/boostorg/release/1.59.0/source/boost_1_59_0.tar.gz #下面的mysql是自带boost的 # mysql安装包获取 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.26.tar.gz5.7版本以后需要使用boost不同版本的Mysql使用的boost版本不同2.安装安装cmaketar -zxvf cmake-3.14.2.tar.gz && cd cmake-3.14.2 ./configure --prefix=/usr/local/cmake # 编译完会提示使用gmake # 在centos上gmake和make都是GUN make 在某些发行版上make不是GUN make就需要使用gmake,这里使用make就行 make && make install安装mysql# 检测是否有mysql用户 id mysql # 创建mysql用户 groupadd -g 550 mysql useradd -g mysql -u 550 mysql # 创建mysql安装目录 版本号5.5 mkdir /server/mysql57 # 解压安装包并进入目录 tar -zxvf mysql-boost-5.7.26.tar.gz && cd mysql-5.7.26 /usr/local/cmake/bin/cmake . -DCMAKE_INSTALL_PREFIX=/server/mysql57 \ -DMYSQL_DATADIR=/server/mysql57/data \ -DWITH_BOOST=./boost/boost_1_59_0/ \ #使用mysql安装包自带的boost -DSYSCONFDIR=/etc \ -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DWITH_ARCHIVE_STORAGE_ENGINE=1 \ -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ -DWITH_PARTITION_STORAGE_ENGINE=1 \ -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \ -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \ -DWITHOUT_FEDERATED_STORAGE_ENGINE=1 \ -DDEFAULT_CHARSET=utf8 \ -DDEFAULT_COLLATION=utf8_general_ci \ -DWITH_EXTRA_CHARSETS=all \ -DENABLED_LOCAL_INFILE=1 \ -DWITH_READLINE=1 \ -DMYSQL_UNIX_ADDR=/server/mysql57/mysql.sock \ -DMYSQL_TCP_PORT=3306 \ -DENABLE_DTRACE=0 \ -DWITH_DEBUG=1 make && make install这一步编译时间较长#增加环境变量 vim /etc/profile # 添加到最后一行，保存 PATH=/server/mysql57/bin:/server/mysql57/lib:$PATH source /etc/profile # 导入新的环境变量初始化配置# 创建数据存储目录 mkdir /server/mysql57/data # 创建日志存放目录 mkdir /server/mysql57/log # 创建日志文件 touch /server/mysql57/log/mariadb.log #编辑配置文件 vim /etc/my.cnf编辑配置文件[mysqld] datadir=/server/mysql57/data socket=/server/mysql57/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Settings user and group are ignored when systemd is used. # If you need to run mysqld under a different user or group, # customize your systemd unit file for mariadb according to the # instructions in http://fedoraproject.org/wiki/Systemd # 自定义内容 explicit_defaults_for_timestamp=true port=3306 user=mysql [mysqld_safe] log-error=/server/mysql57/log/mariadb.log pid-file=/server/mysql57/mariadb.pid # # include all files from the config directory # !includedir /etc/my.cnf.d初始化#两种方式 使用配置文件和使用参数 # 1.使用配置文件初始化 mysqld --defaults-file=/etc/my.cnf --initialize # 2. 使用参数初始化 mysqld --initialize --user=mysql --basedir=/server/mysql57 --datadir=/server/mysql57/data # 两种方式哪种都可以 # 初始化成功后会生成root用户的密码 # 使用--initialize-insecure代替--initialize就不会生成root的密码，root为无密码账户 # 读写权限 chown -R mysql:mysql /server/mysql # 因为配置文件中用到的目录都在此目录下，所以一个命令就搞定，如果在不同的目录，需要分别授权或者修改目录所有者 # 复制启动脚本到/etc/init.d cp /server/mysql55/support-files/mysql.server 启动Mysql服务service mysqld start # 启动服务 # 正常情况下能启动成功，出现问题可查看日志找到具体错误 cat /server/mysql57/log/mariadb.log故障处理如果服务启动成功，使用mysql通过socket连接本地服务提示Segmentation fault (core dumped)修改源码重新编译vim ./mysql-5.7.26/cmd-line-utils/libedit/terminal.c #将869行注释 /*char buf[TC_BUFSIZE];*/ # 将879行修改 原 area = buf; 修改为 area = NULL; # 然后重新cmake make make install 安装Apache获取源码包# 获取apache wget http://mirror.bit.edu.cn/apache//httpd/httpd-2.4.29.tar.gz # 新版apache不包含apr和apr-util # 获取 apr wget http://mirror.bit.edu.cn/apache//apr/apr-1.6.3.tar.gz # 获取apr-util源码包 wget http://archive.apache.org/dist/apr/apr-util-1.5.2.tar.gz # 获取pcre源码包 wget https://ftp.pcre.org/pub/pcre/pcre-8.41.tar.gz安装aprmkdir /server/apr tar tar -zxvf apr-1.6.5.tar.gz cd apr-1.6.5 ./configure --prefix=/server/apr make && make install安装apr-utiltar -jxvf apr-util-1.6.1.tar.bz2 cd apr-util-1.6.1 ./configure --prefix=/server/apr-util --with-apr=/server/apr make && make install安装pcremkdir /server/pcre tar -zxvf pcre-8.41.tar.gz cd pcre-8.41 ./configure --prefix=/server/pcre make && make install安装Apacheapache编译参数详解：https://blog.51cto.com/superleedo/1890080groupadd www # 创建一个不允许登录的用户www 属于www用户组 useradd -g www www -s /bin/false mkdir /server/httpd # apache安装目录 mkdir /server/www # web服务根目录 tar -zxvf httpd-2.4.38.tar.gz cd httpd-2.4.38 ./configure --prefix=/server/httpd \ --with-apr=/server/apr \ --with-apr-util=/server/apr-util \ --with-pcre=/server/pcre \ --sysconfdir=/server/httpd/conf \ --datadir=/server/www \ --enable-so \ --enable-deflate=shared \ --enable-expires=shared \ --enable-rewrite=shared \ --enable-cache makemake时，如果出现undefined reference to "XML_GetErrorCode"错误，需要安装libxml2-devel，并重新编译安装apr-utilrm /server/apr-util/* -rf cd /server/source/apr-util-1.6.1 make clean ./configure --prefix=/server/apr-util --with-apr=/server/apr make && make install然后重新执行httpd 编译 configure修改配置文件vim /server/httpd/conf/httpd.conf162行附近 修改User daemon 为 www163行附近 修改Group daemon 为 www193行附近 修改为 ServerName 127.0.0.1:80保存chown -R www /server/www/* cp /server/httpd/bin/apachectl /etc/init.d/httpd # 启动服务 /etc/init.d/httpd start虚拟机测试可能需要关闭防火墙，或者开通对应端口systemctl stop firewalld.service安装php资源获取wget https://www.php.net/distributions/php-5.6.38.tar.gz wget https://downloads.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz安装libmcryptmkdir /usr/local/libmcrypt tar -zxvf libmcrypt-2.5.8.tar.gz cd libmcrypt-2.5.8 ./configure --prefix=/usr/local/libmcrypt make make install安装phptar -zxvf php-5.6.38.tar.gz cd php-5.6.38 ./configure --prefix=/server/php56 \ --with-apxs2=/server/httpd/bin/apxs \ --with-openssl \ --with-mysqli \ --with-pdo-mysql \ --enable-mbstring \ --with-zlib \ --enable-sockets \ --with-curl \ --with-pcre-regex \ --with-mcrypt=/usr/local/libmcrypt \ --with-gd \ --with-png-dir \ --with-freetype-dir \ --enable-gd-native-ttf \ --enable-opcache make make test make install cp /server/source/php-5.6.38/php.ini-development /server/php56/lib/php.ini # 修改httpd配置文件 vim /server/httpd/conf/httpd.conf # 添加如下内容 <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> # 启动httpd服务 /etc/init.d/httpd start
php编译安装的基本步骤//首先要下载一个php的安装包,例如:php-5.6.25.tar.gz,tar zxvf php-5.6.25.tar.gz // 解压php安装包,得到一个php-5.6.25的文件夹 cd php-5.6.25 ./configure //对php的安装进行配置,后面要加配置选项 # make && make install //编译安装完成之后,需要从解压后的文件夹中把php.ini-development //或是 php.ini-production 重命名成php.ini 复制到php安装文件中的相应位置, //可在phpinfo中查看 相应位置. // 把/usr/local/php/etc/php-fpm.conf.default 复制到当前文件夹下,保存未php-fpm.conf上面是php编译安装的基本流程,下面详细介绍php的配置参数.php各参数配置详解--prefix=/usr/local/php //指定 php 安装目录--with-apxs2=/usr/local/apache/bin/apxs //整合apache， //apxs功能是使用mod_so中的LoadModule指令， //加载指定模块到 apache，要求 apache 要打开SO模块--with-config-file-path=/usr/local/php/etc //指定php.ini位置--with-MySQL=/usr/local/mysql //mysql安装目录，对mysql的支持--with-mysqli=/usr/local/mysql/bin/mysql_config //mysqli扩展技术不仅可以调用MySQL的存储过程、处理MySQL事务， //而且还可以使访问数据库工作变得更加稳定。--enable-safe-mode //打开安全模式 --enable-ftp //打开ftp的支持 --enable-zip //打开对zip的支持 --with-bz2 //打开对bz2文件的支持 --with-jpeg-dir //打开对jpeg图片的支持 --with-png-dir //打开对png图片的支持 --with-freetype-dir //打开对freetype字体库的支持 --without-iconv //关闭iconv函数，各种字符集间的转换 --with-libXML-dir //打开libxml2库的支持 --with-XMLrpc //打开xml-rpc的c语言 --with-zlib-dir //打开zlib库的支持 --with-gd //打开gd库的支持 --enable-gd-native-ttf //支持TrueType字符串函数库 --with-curl //打开curl浏览工具的支持 --with-curlwrappers //运用curl工具打开url流 --with-ttf //打开freetype1.*的支持，可以不加了 --with-xsl //打开XSLT 文件支持，扩展了libXML2库 ，需要libxslt软件 --with-gettext //打开gnu 的gettext 支持，编码库用到 --with-pear //打开pear命令的支持，PHP扩展用的 --enable-calendar //打开日历扩展功能 --enable-mbstring //多字节，字符串的支持 --enable-bcmath //打开图片大小调整,用到zabbix监控的时候用到了这个模块--enable-sockets //打开 sockets 支持--enable-exif //图片的元数据支持 --enable-magic-quotes //魔术引用的支持 --disable-rpath //关闭额外的运行库文件 --disable-debug //关闭调试模式 --with-mime-magic=/usr/share/file/magic.mime //魔术头文件位置CGI方式安装才用的参数:--enable-fpm //打上PHP-fpm 补丁后才有这个参数，CGI方式安装的启动程序--enable-fastCGI //支持fastcgi方式启动PHP--enable-force-CGI-redirect //重定向方式启动PHP--with-ncurses //支持ncurses 屏幕绘制以及基于文本终端的图形互动功能的动态库--enable-pcntl //freeTDS需要用到的，可能是链接mssql 才用到--with-mcrypt //mcrypt算法的扩展--with-mhash //mhash算法的扩展//以上函数库需要安装--with-gmp //应该是支持一种规范--enable-inline-optimization //优化线程--with-openssl //openssl的支持，加密传输时用到的--enable-dbase //建立DBA 作为共享模块--with-pcre-dir=/usr/local/bin/pcre-config //perl的正则库案安装位置--disable-dmalloc--with-gdbm //dba的gdbm支持--enable-sigchild--enable-sysvsem--enable-sysvshm--enable-zend-multibyte //支持zend的多字节--enable-mbregex--enable-wddx--enable-shmop--enable-soap注意事项指定了--with-apxs2=/usr/local/apache/bin/apxs以后，就不要再激活--enable-fpm和--enable-fastCGI，apxs是以php module的模式加载PHP的。Mysql在编译了Mysql开发library以后，可以不用指定mysql的路径。PHP编译存在基础的依赖的关系，编译PHP首先需要安装XML扩展，因为php5核心默认打开了XML的支持，其他的基础库，相应需要：GD -> zlib, Png, Jpg, 如果需要支持其他，仍需要根据实际情况编译扩展库，ttf库需要freetype库的支持。--enable-magic-quotes，是一个极其不推荐的参数，当然，如果你需要PHP为你做这些底下的工作，实际上他也没有很彻底的解决问题。--with-openssl，需要openssl库。mysqli是MySQL团队提供的MySQL驱动，具有很多实用的功能和典型特征。不过他不是MySQL于PHP平台最好的选择，PDO被证实，是一个简易、高并发性，而且易于创建和回收的标准接口。不过PDO也经历了5.3以前的内存溢出的问题，在5.3以后，在读取Oracle的LOB资源时，若不对内存进行限制，仍会内存溢出。如果是产品模式，好像pear、shmop、ftp等，都不推荐使用，他们要做的事情，用C/C++，用Java，甚至其他脚本语言，都有很好很快速的选择，无需局限于使用PHP去实现。不熟悉的类库和不常用的库，也不推荐使用。magic-quote、session.auto_start、PHP服务器信息、PHP报错信息等在编译完成后，应该第一时间关闭，避免暴露服务器信息。PHP对应的Web Server模式，Module、fastcgi、fpm只需要一种即可，服务器不是你的试验田。fastcgi可以选择Nginx和lighttpd，其实Nginx也是使用lighttpd的spwan-fcgi进行fcgi进程管理的。fpm是使用PHP自身去管理多进程，有点类似一个后端代理。无论什么模式，在发布产品服务器，都应该做进程和线程调优，做足够多的压力测试，找出最好的进程数组合。选好一种PHP OPCode cache的扩展，这个也是很重要的，linux 2.6核心下，fcgi下，xcache有较好的实践经验，其他的在并发数增加以后，性能衰减严重。如果真的想体验，宁可编译多几个PHP版本，也不要针对一个版本的PHP集合各种扩展，适应各种环境，这会让把你自己逼进窘境的。需要单独安装的扩展gd库。ming的扩展。mhash和mcrypt的扩展。详细选项上，除了上述的安装简介外，也可以在编译时加入其它的选项。apache 模块语法: --with-apache=DIR说明: 用本选项可以让 **PHP** 以apache的模块方式使用，DIR 的字符串可以是 /usr/local/apache 或其它安装apache的目录范例: --with-apache=/var/lib/apachefhttpd 服务器模块语法: --with-fhttpd=DIR说明: 若使用 fttpd 服务器，可以使用本指令编译 PHP。用模块的方式配合 fttpd 服务器，可以有较好的效率。Adabas D 数据库语法: --with-adabas=DIR说明: 数据库系统为 Adabas D 数据库时需要加本选项。关于 Adabas D 数据库的细节，可以参考 http://www.adabas.com。范例: --with-adabas=/usr/local/adabasddBase 资料表语法: --with-dbase说明: 只要加本选项，不用其它的参数或函数库，PHP 就会让系统有存取 dBase 资料表的功能。filePro 数据库语法: --with-filepro说明: 不用指定数据库路径及其它函数库等，可以读取 filePro 数据库 (唯读)。mSQL 数据库语法: --with-msql=DIR说明: 提供存取 mSQL 数据库。更多的细节请参考 mSQL 的网站 http://www.hughes.com.au。范例: --with-msql=/usr/local/HughesMySQL 数据库语法: --with-mysql=DIR说明: 提供存取 MySQL 数据库。更多的细节请参考 MySQL 的网站 http://www.tcx.se。范例: --with-mysql=/usr/local/mysqliODBC 数据库装置语法: --with-iodbc=DIR说明: 提供 ODBC 数据库装置，用来存取后端数据库。更多的细节请参考 iODBC 的网站 http://www.iodbc.org。范例: --with-iodbc=/usr/local/iodbcOpenLink ODBC 数据库装置语法: --with-openlink=DIR说明: 使用 OpenLink ODBC 数据库装置，用来存取后端数据库。更多的细节请参考 OpenLink ODBC 的网站 http://www.openlinksw.com。范例: --with-openlink=/usr/local/openlinkOracle 数据库语法: --with-oracle=DIR说 明: 使用 Oracle 数据库。Oracle 的版本要在 7.3 版以上。您也可以在 PHP 程序中使用环境变量 ORACLE_HOME 来指定 Oracle 的路径。更多有关 Oracle 的信息请参考 Oracle 的网站 http://www.oracle.com。范例: --with-oracle=/export/app/oracle/product/7.3.2PostgreSQL 数据库语法: --with-pgsql=DIR说 明: 使用 PostgreSQL 数据库。更多有关 PostgreSQL 的信息请参考 PostgreSQL 的网站 http://www.postgreSQL.org 或台湾的 Mirror 站 http://postgresql.ccit.edu.tw。范例: --with-pgsql=/usr/local/pgsqlSolid 数据库语法: --with-solid=DIR说明: 使用 Solid 数据库。更多有关 Solid 的信息请参考 Solid 的网站 http://www.solidtech.com。范例: --with-solid=/usr/local/solidSybase 数据库语法: --with-sybase=DIR说明: 使用 Sybase 数据库。更多有关 Sybase 的信息请参考 Sybase 的网站 http://www.sybase.com。范例: --with-sybase=/home/sybaseSybase-CT 数据库语法: --with-sybase-ct=DIR说明: 使用 Sybase-CT 数据库。范例: --with-sybase-ct=/home/sybaseVelocis 数据库语法: --with-velocis=DIR说明: 使用 Velocis 数据库。有关 Velocis 数据库的进一步资料请参考 Raima 公司的网站 http://www.raima.com。范例: --with-velocis=/usr/local/velocis自订 ODBC 数据库驱动程序语法: --with-custom-odbc=DIR说明: 使用自订的 ODBC 函数库。当然，在使用本方式时要指定 CUSTOM_ODBC_LIBS 及 CFLAGS 变量。例如在 QNX 机器上使用 Sybase **SQL** Anywhere 时可能要配置系统环境变量 CFLAGS=-DODBC_QNX、LDFLAGS=-lunix 及 CUSTOM_ODBC_LIBS="-ldblib -lodbc"，并要在 PHP 配置加入 --with-custom-odbc=/usr/lib/sqlany50范例: --with-custom-odbc=/usr/local/odbc不使用 ODBC 数据库驱动程序语法: --disable-unified-odbc说 明: 使用本选项将使所有的 ODBC 数据库驱动程序不作用。本选项不用指定路径，而受本选项影响的选项有 --with-iodbc、--with-solid、--with-adabas、--with-velocis 及 --with-custom-odbc。LDAP 目录协议语法: --with-ldap=DIR说明: 若要使用目录协议 (Lightweight Directory Access Protocol, LDAP) 则必须要打开本选项。有关 LDAP 的细节，可以参考 RFC 文件的 RFC1777 及 RFC1778。范例: --with-ldap=/usr/local/ldap.mcrypt 编码函数库语法: --with-mcrypt=DIR说明: 当安装了 mcrypt 函数库后，可在编译 PHP 时加入本选项，让程序可以使用编解码功能。范例: --with-mcrypt=/usr/local/includeSys V 信号语法: --enable-sysvsem说明: 要使用 SysV 的信号 (semaphores) 机制，则要打开本选项。XML 支持语法: --with-xml说明: 打开本选项可以支持 James Clark's 写的 XML 解析程序库。维护模式语法: --enable-maintainer-mode说明: 本选项一般不会打开，除非是 PHP 开发人员比较有用。正则表达式程序库语法: --with-system-regex说明: 若您需要额外的正则表达式功能，可以加入本选项。PHP 配置文件语法: --with-config-file-path=DIR说明: 用来指定 php3.ini 或 php4.ini 的路径，供 PHP 初始化时使用。范例: --with-config-file-path=/usr/local/libPHP 执行路径语法: --with-exec-dir=DIR说明: 有时为了系统的安全性考虑，会指定 PHP 程序一定要在哪个目录执行。范例: --with-exec-dir=/usr/local/bin调试模式语法: --enable-debug说明: 本选项一般不会使用，除非在开发 PHP 程序时比较有用。它可以显示额外的错误信息。安全模式语法: --enable-safe-mode说明: 默认值是打开的，可以对系统安全提供比较多的保护。变量追踪语法: --enable-track-vars说明: 让 PHP 能 追踪 HTTP_GET_VARS、HTTP_POST_VARS 及 HTTP_COOKIE_VARS 三个变量，一般是打开的。自动加引入字符语法: --enable-magic-quotes说明: 可让程序在执行时自动加入反斜线的引入字符。打开调试器语法: --enable-debugger说明: 打开内建的 PHP 调试器。目前本功能还在实验阶段，尚未成熟。取消路径 (discard path)语法: --enable-discard-path说明: 打开这个选项，**用户**就不能透过浏览器读取 .htaccess 等和系统安全相关的文件。高精确度数学函数语法: --enable-bcmath说明: 打开高精确度函数。必须要先安装本函数库，本选项方有效。强制 CGI 重定向语法: --enable-force-cgi-redirect范 例: 若使用 CGI VERSION 模式来执行 PHP 的设，打开本选项会增加安全性。例如用户读 http://my.host/cgi-bin/php/secret/doc.html 遇到比较了解 PHP 系统的黑客级用户可能会自已输入以下网址 http://my.host/secret/doc.html 来读取相关信息。若 PHP 和 Apache 编译在一起，让 PHP 变成 Apache 的一部份，则不需要加入本选项。不使用短的标记语法: --disable-short-tags说明: 配置本选项后，PHP 的程序就不能使用短的标记，一定要用的长标记。引入远端档宁语法: --enable-url-includes说明: 配置本选项可让 PHP 程序可以引入 (include) 远端的 HTTP 或 FTP 服务器中的文件。关闭语法效果语法: --disable-syntax-hl说明: 使用本选项会关闭 PHP 语法的彩色效果。函数库路径语法: CPPFLAGS=-IDIR 及 LDFLAGS=-LDIR说明: 若 PHP 在安全或编译所需的函数库在值得的路径，需要加入本选项，LDFLAGS 表示函数库的路径，CPPFLAGS 表示标头文件的路径。范例: LDFLAGS=-L/my/lib/dir CPPFLAGS=-I/my/include/dir ./configure配置项代码./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php --enable-mysqlnd --enable-opcache --enable-sockets --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-shmop --enable-zip --enable-ftp --enable-soap --enable-xml --enable-mbstring --disable-rpath --disable-debug --disable-fileinfo --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-pcre-regex --with-iconv --with-zlib --with-gd --with-openssl --with-xmlrpc --with-curl --with-imap-ssl --with-freetype-dir --enable-fpm --enable-pcntl --with-mcrypt --with-mhash
获取数组随机几项，可指定获取数量/** * 获取数组随机项 * @param $arr array 源数组 * @param int $num 获取的随机项个数 * @return array|bool 结果数组 */ function get_random_array($arr, $num = 1) { if (count($arr) < $num) { return false; } $ids = array_rand($arr, $num); $res = array_filter($arr, function($k) use ($ids) { return in_array($k, $ids); }, ARRAY_FILTER_USE_KEY); return $res; }
/** * @param int http状态码 */ function httpStatus($num) { static $http = array( 100 => "HTTP/1.1 100 Continue", 101 => "HTTP/1.1 101 Switching Protocols", 200 => "HTTP/1.1 200 OK", 201 => "HTTP/1.1 201 Created", 202 => "HTTP/1.1 202 Accepted", 203 => "HTTP/1.1 203 Non-Authoritative Information", 204 => "HTTP/1.1 204 No Content", 205 => "HTTP/1.1 205 Reset Content", 206 => "HTTP/1.1 206 Partial Content", 300 => "HTTP/1.1 300 Multiple Choices", 301 => "HTTP/1.1 301 Moved Permanently", 302 => "HTTP/1.1 302 Found", 303 => "HTTP/1.1 303 See Other", 304 => "HTTP/1.1 304 Not Modified", 305 => "HTTP/1.1 305 Use Proxy", 307 => "HTTP/1.1 307 Temporary Redirect", 400 => "HTTP/1.1 400 Bad Request", 401 => "HTTP/1.1 401 Unauthorized", 402 => "HTTP/1.1 402 Payment Required", 403 => "HTTP/1.1 403 Forbidden", 404 => "HTTP/1.1 404 Not Found", 405 => "HTTP/1.1 405 Method Not Allowed", 406 => "HTTP/1.1 406 Not Acceptable", 407 => "HTTP/1.1 407 Proxy Authentication Required", 408 => "HTTP/1.1 408 Request Time-out", 409 => "HTTP/1.1 409 Conflict", 410 => "HTTP/1.1 410 Gone", 411 => "HTTP/1.1 411 Length Required", 412 => "HTTP/1.1 412 Precondition Failed", 413 => "HTTP/1.1 413 Request Entity Too Large", 414 => "HTTP/1.1 414 Request-URI Too Large", 415 => "HTTP/1.1 415 Unsupported Media Type", 416 => "HTTP/1.1 416 Requested range not satisfiable", 417 => "HTTP/1.1 417 Expectation Failed", 500 => "HTTP/1.1 500 Internal Server Error", 501 => "HTTP/1.1 501 Not Implemented", 502 => "HTTP/1.1 502 Bad Gateway", 503 => "HTTP/1.1 503 Service Unavailable", 504 => "HTTP/1.1 504 Gateway Time-out" ); header($http[$num]); }
function deldir($dir) { if (false === is_dir($dir)) { return true; } //先删除目录下的文件： $dh = opendir($dir); while ($file = readdir($dh)) { if ($file != "." && $file != "..") { $fullpath = $dir . "/" . $file; if (!is_dir($fullpath)) { unlink($fullpath); } else { deldir($fullpath); } } } closedir($dh); //删除当前文件夹： if (rmdir($dir)) { return true; } else { return false; } }
fast_cgi模式下php5.6报错 "No input file specified"
//默认伪静态 <IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] </IfModule> 修改后的伪静态 <IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L] </IfModule> //仅仅就是在正则结果“/$1”前面多加了一个“?”号，问题也就随之解决了。