- 工信部备案号 滇ICP备05000110号-1
- 滇公安备案 滇53010302000111
- 增值电信业务经营许可证 B1.B2-20181647、滇B1.B2-20190004
- 云南互联网协会理事单位
- 安全联盟认证网站身份V标记
- 域名注册服务机构许可:滇D3-20230001
- 代理域名注册服务机构:新网数码
模块内部封装了很多实用的功能,有时在模块外部调用就需要将其导入。常见的方式有如下几种:1 . import>>> import sys>>> sys.path['', 'C:\\Python34\\Lib\\idlelib', 'C:\\Windows\\system32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']最常见的方式,直接将要导入的模块名称写在后面导入。2 .from .. import ..与import类似,只是更明确的要导入的方法或变量,比如:>>> from sys import path>>> path['', 'C:\\Python34\\Lib\\idlelib', 'C:\\Windows\\system32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']但是会造成命名空间的污染,更推荐使用import。3 . 用名称字符串导入模块我们可能想这样导入模块:>>> import "sys"SyntaxError: invalid syntaxpython import接收的是变量而不是字符串,那将”sys”赋值给一个变量呢?>>> x="sys">>> import xTraceback (most recent call last): File "<pyshell#4>", line 1, in <module> import xImportError: No module named 'x'这样也不行,这样做的意思是导入名为x的模块而非x代表的sys模块。我们需要用到exec函数:>>> x="sys">>> exec("import "+ x)>>> sys.path['', 'C:\\Python34\\Lib\\idlelib', 'C:\\Windows\\system32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']将导入语句构建成字符串并传递给exec函数执行。exec缺点是每次执行都要编译,运行多次会影响性能。更好的方式是使用__import__ 函数。>>> x="sys">>> sys = __import__(x)>>> sys.path['', 'C:\\Python34\\Lib\\idlelib', 'C:\\Windows\\system32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']这种方式需要一个变量保存模块对象,以便后续调用。
free 命令相对于top 提供了更简洁的查看系统内存使用情况: # free total used free shared buffers cached Mem: 255988 231704 24284 0 6432 139292 -/+ buffers/cache: 85980(used2) 170008(free2) Swap: 746980 0 746980 Mem:表示物理内存统计 -/+ buffers/cached:表示物理内存的缓存统计 Swap:表示硬盘上交换分区的使用情况,这里我们不去关心。 系统的总物理内存:255988Kb(256M),但系统当前真正可用的内存并不是第一行free 标记的 24284Kb,它仅代表未被分配的内存。 total:表示物理内存总量。 used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。 free:未被分配的内存。 shared:共享内存,一般系统不会用到,这里也不讨论。 buffers:系统分配但未被使用的buffers 数量。 cached:系统分配但未被使用的cache 数量。buffer 与cache 的区别见后面。 used2:实际使用的buffers 与cache 总量,也是实际使用的内存总量。 free2:未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。 可以整理出如下等式: total = used + free total = used2 + free2 used = buffers + cached + used2 free2 = buffers + cached + free buffer 与cache 的区别 A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use.
linux drwxr-xr-x 第一位表示文件类型。d是目录文件,l是链接文件,-是普通文件,p是管道第2-4位表示这个文件的属主拥有的权限,r是读,w是写,x是执行。第5-7位表示和这个文件属主所在同一个组的用户所具有的权限。第8-10位表示其他用户所具有的权限。 如:$ ls -altotal 16drwxr-xr-x 8 bin bin 256 Dec 06 11:09 .drwxr-xr-x 25 root system 4096 Feb 23 11:21 ..drwxr-xr-x 2 develop others 256 Oct 12 2012 developdrwxr-xr-x 2 guest usr 256 Aug 31 2010 guestdrwxr-xr-x 12 ibm staff 4096 May 29 11:14 ibmdrwx------ 2 root system 256 Dec 06 10:36 lost+founddrwxr-xr-x 3 oracle staff 256 Feb 05 16:31 oracledrwxr-xr-x 2 202 201 256 Dec 06 2011 sshd 用ibm登录?则不能在oracle用户下进行写入操作,oracle与ibm在同一个组下面(staff).只有xr权限,只能读和执行。 linux ls -al 的各段含义第1字段: 文件属性字段 文件属性字段总共有10个字母组成,第一个字母表示文件类型,如果这个字母是一个减号”-”,则说明该文件是一个普通文件.字母”d”表示该文件是一个目录,字母”d”,是dirtectory(目录)的缩写. 请注意,一个目录或者说一个文件夹是一个特殊文件,这个特殊文件存放的是其他文件和文件夹的相关信息. 第2字段 文件硬链接数或目录子目录数 第3字段: 文件拥有者 第4字段: 文件拥有者所在的组 第5字段: 文件文件大小(以字节为单位) 第6字段: 文件创建月份 第7字段: 文件创建日期 第8字段: 文件创建时间 第9字段: 文件名 (如果是一个符号链接,那么会有一个 “->” 箭头符号,后面根一个它指向的文件) chmod 755chmod是Linux下设置文件权限的命令,后面的数字表示不同用户或用户组的权限。 一般是三个数字: 第一个数字表示文件所有者的权限 第二个数字表示与文件所有者同属一个用户组的其他用户的权限 第三个数字表示其它用户组的权限。 权限分为三种:读(r=4),写(w=2),执行(x=1) 。 综合起来还有可读可执行(rx=5=4+1)、可读可写(rw=6=4+2)、可读可写可执行(rwx=7=4+2+1)。 所以,chmod 755 设置用户的权限为: 1.文件所有者可读可写可执行 --72.与文件所有者同属一个用户组的其他用户可读可执行 --5 3.其它用?组可读可执行 --5
下载了个apache-tomcat-8.0.5.zip免安装压缩包,解压之后配置了CATALINA_HOME等等后启动不了。tomcat8启动出现的错误log如下:Using CATALINA_BASE: "E:apache-tomcat-8.0.5"Using CATALINA_HOME: "E:apache-tomcat-8.0.5"Using CATALINA_TMPDIR: "E:apache-tomcat-8.0.5 emp"Using JRE_HOME: "D:jdk1.6.0_31"Using CLASSPATH: "E:apache-tomcat-8.0.5inootstrap.jar;E:apache-tomcat-8.0.5in omcat-juli.jar"Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/catalina/startup/Bootstrap : Unsupported major.minor version 51.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) at java.lang.ClassLoader.defineClass(ClassLoader.java:615) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) at java.net.URLClassLoader.access$000(URLClassLoader.java:58) at java.net.URLClassLoader$1.run(URLClassLoader.java:197) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247)Heap经查询此问题为java jdk和jre版本不同所致。猜测tomcat 8下部署的class是使用jdk 1.7编写并编译的,而我java_home中的jre为1.6版本的。所以就下载了一个1.7版本,将类编译成jdk 1.7版本,问题解决。
1.关于Tomcat的session数目 这个可以直接从Tomcat的web管理界面去查看即可 或者借助于第三方工具Lambda Probe来查看,它相对于Tomcat自带的管理稍微多了点功能,但也不多 2.监视Tomcat的内存使用情况 使用JDK自带的jconsole可以比较明了的看到内存的使用情况,线程的状态,当前加载的类的总量等 JDK自带的jvisualvm可以下载插件(如GC等),可以查看更丰富的信息。如果是分析本地的Tomcat的话,还可以进行内存抽样等,检查每个类的使用情况 3.打印类的加载情况及对象的回收情? 这个可以通过配置JVM的启动参数,打印这些信息(到屏幕(默认也会到catalina.log中)或者文件),具体参数如下: -XX:+PrintGC:输出形式:[GC 118250K->113543K(130112K), 0.0094143 secs] [Full GC 121376K->10414K(130112K), 0.0650971 secs] -XX:+PrintGCDetails:输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs] [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs] -XX:+PrintGCTimeStamps -XX:+PrintGC:PrintGCTimeStamps可与上面两个混合使用,输出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs] -XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间。可与上面混合使用。输出形式:Application time: 0.5291524 seconds -XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间。可与上面混合使用。输出形式:Total time for which application threads were stopped: 0.0468229 seconds -XX:PrintHeapAtGC: 打印GC前后的详细堆栈信息 -Xloggc:filename:与上面几个配合使用,把相关日志信息记录到文件以便分析 -verbose:class 监视加载的类的情况 -verbose:gc 在虚拟机发生内存回收时在输出设备显示信息 -verbose:jni 输出native方法调用的相关情况,一般用于诊断jni调用错误信息 4.添加JMS远程监控 对于部署在局域网?其它机器上的Tomcat,可以打开JMX监控端口,局域网其它机器就可以通过这个端口查看一些常用的参数(但一些比较复杂的功能不支持),同样是在JVM启动参数中配置即可,配置如下: -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.71.38 设置JVM的JMS监控监听的IP地址,主要是为了防止错误的监听成127.0.0.1这个内网地址 -Dcom.sun.management.jmxremote.port=1090 设置JVM的JMS监控的端口 -Dcom.sun.management.jmxremote.ssl=false 设置JVM的JMS监控不实用SSL -Dcom.sun.management.jmxremote.authenticate=false 设置JVM的JMS监控不需要认证 5.专业点的分析工具有 IBM ISA,JProfiler等,具体监控及分析方式去网上搜索即可。 集群方案单个Tomcat的处理性能是有限的,当并发量较大的时候,就需要有部署多套来进行负载均衡了。 集群的关键点有以下几点: 1.引入负载端软负载可以使用nginx或者apache来进行,主要是使用一个分发的功能 参考: http://ajita.iteye.com/blog/1715312(nginx负载) http://ajita.iteye.com/blog/1717121(apache负载) 2.共享session处理 目前的处理方式有如下几种: 1).使用Tomcat本身的Session复制功能参考http://ajita.iteye.com/blog/1715312(Session复制的配置)方案的优点是配置简单,缺点是当集群数量较多时,Session复制的时间会比较长,影响响应的效率;2).使用第三方来存放共享Session目前用的较多的是使用memcached来管理共享Session,借助于memcached-sesson-manager来进行Tomcat的Session管理,参考http://ajita.iteye.com/blog/1716320(使用MSM管理Tomcat集群session) 3).使用黏性session的策略 对于会话要求不太强(不涉及到计费,失败了允许重新请求下等)的场合,同一个用户的session可以由nginx或者apache交给同一个Tomcat来处理,这就是所谓的session sticky策略,目前应用也比较多,参考:http://ajita.iteye.com/blog/1848665(tomcat session sticky),nginx默认不包含session sticky模块,需要重新编译才行,优点是处理效率高多了,缺点是强会话要求的场合不合适 3.小结 以上是实现集群的要点,其中1和2可以组合使用,具体场景具体分析吧~ JVM优化Tomcat本身还是运行在JVM上的,通过对JVM参数的调整我们可以使Tomcat拥有更好的性能。针对JVM的优化目前主要在两个方面: 1.内存调优内存方式的设置是在catalina.sh中,调整一下JAVA_OPTS变量即可,因为后面的启动参数会把JAVA_OPTS作为JVM的启动参数来处理。 具体设置如下: JAVA_OPTS="$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4" 其各项参数如下: -Xmx3550m:设置JVM最大可用内存为3550M。 -Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 -Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。 -Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行 调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6。-XX:MaxPermSize=16m:设置持久代大小为16m。-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。 对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概论。2.垃圾回收策略调优垃圾回收的设置也是在catalina.sh中,调整JAVA_OPTS变量。具体设置如下: JAVA_OPTS="$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100" 具体的垃圾回收策略及相应策略的各项参数如下: 串行收集器?JDK1.5以前主要的回收方式) -XX:+UseSerialGC:设置串行收集器 并行收集器(吞吐量优先) 示例:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。-XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集。-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最?相应时间或者收集频率等,此值建议使用并行收集器时,一直打开。并发收集器(响应时间优先)示例:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:+UseConcMarkSweepGC:设置年老代为并发收集。测试中配置这个以后,-XX:NewRatio=4的配置失效了,原因不明。所以,此时年轻代大小最好用-Xmn设置。 -XX:+UseParNewGC: 设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需?设置此值。-XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片。3.小结在内存设置中需要做一下权衡1)内存越大,一般情况下处理的效率?越高,但同时在做垃圾回收的时候所需要的时间也就越长,在这段时间内的处理效率是必然要受影响的。2)在大多数的网络文章中都推荐 Xmx和Xms设置为一致,说是避免频繁的回收,这个在测试的时候没有看到明显的效果,内存的占用情况基本都是锯齿状的效果,所以这个还要根据实际情况来定。Server.xml的Connection优化Tomcat的Connector是Tomcat接收HTTP请求的关键模块,我们可以配置它来指定IO模式,以及处理通过这个Connector接受到的请求的处理线程数以及其它一些常用的HTTP策略。其主要配置参数如下:1.指定使用NIO模型来接受HTTP请求protocol="org.apache.coyote.http11.Http11NioProtocol" 指定使用NIO模型来接受HTTP请求。默认是BlockingIO,配置为protocol="HTTP/1.1" acceptorThreadCount="2" 使用NIO模型时接收线程的数目 2.指定使用线程池来处理HTTP请求 首先要配置一个线程池来处?请求(与Connector是平级的,多个Connector可以使用同一个线程池来处理请求) <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="1000" minSpareThreads="50" maxIdleTime="600000"/> <Connector port="8080" executor="tomcatThreadPool" 指定使用的线程池 3.指定BlockingIO模式下的处理线程数目maxThreads="150"//Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数。默认值200。可以根据机器的时期性能和内存大小调整,一般可以在400-500。最大可以在800左右。minSpareThreads="25"---Tomcat初始化时创建的线程数。默认值4。如果当前没有空闲线程,且没有超过maxThreads,一次性创建的空闲线程数量。Tomcat初始化时创建的线程数量也由此值设置。maxSpareThreads="75"--一旦创建的线程超过这个值,Tomcat就会关闭不?需要的socket线程。默认值50。一旦创建的线程 超过此数值,Tomcat会关闭不再需要的线程。线程数可以大致上用 “同时在线人数*每秒用户操作次数*系统平均操作时间” 来计算。acceptCount="100"----指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处 理。默认值10。如果当前可用线程数为0,则将请求放入处理队列中。这个值限定了请求队列的大小,超过这个数值的请求将不予处理。connectionTimeout="20000" --网络连接超时,默认值20000,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。4.其它常用设置maxHttpHeaderSize="8192" http请求头信息的最大程度,超过此长度的部分不予处理。一般8K;URIEncoding="UTF-8" 指定Tomcat容器的URL编码格式;disableUploadTimeout="true" 上传时是否使用超时机制;enableLookups="false"--是否反查域名,默认值为true,为了提高处理能力,应设置为false;compression="on" 打开压缩功能;compressionMinSize="10240" 启用压缩的输出内容大小,默认为2KB;noCompressionUserAgents="gozilla, traviata" 对于以下的浏览器,不启用压缩;compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 哪些资源类型需要压缩。5.小结关于Tomcat的Nio和ThreadPool,本身的引入就提高了处理的复杂性,所以对于效率的提高有多少,需要实际验证一下。6.配置示例 <Connector port="8080" redirectPort="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" acceptCount="100" connectionTimeout="20000" protocol="HTTP/1.1" maxHttpHeaderSize="8192" URIEncoding="UTF-8" disableUploadTimeout="true" enableLookups="false" compression="on" compressionMinSize="10240" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"> ... </Connector> 管理AJP端口AJP是为 Tomcat 与 HTTP 服务器之间通信而定制的协议,能提供较高的通信速度和效率。如果tomcat前端放的是apache的时候,会使用到AJP这个连接器。由于我们公司前端是由nginx做的反向代理,因此不使用此连接器,因此需要注销掉该连接器。<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->默认 Tomcat 是开启了对war包的热部署的。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。修改实例:<Host name="localhost" appBase="" unpackWARs="false" autoDeploy="false">
Tomcat的localhost页面在本机可以正常访问。但是远程计算机访问或者本机用ip:端口访问就不行。下面是解决办法:1. 前提是你已经配好了tomcat_user.xml,server.xml,context.xml。2. 在tomat_home/conf/Catalina/localhost/下添加manager.xml,录入以下内容:<Context privileged="true" antiResourceLocking="false" docBase="${catalina.home}/webapps/manager"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="^.*$" /> </Context>3. 属性allow是ip限制,可以改成这样 allow="127.0.0.1,192.168.1.*",意思是只允许本机和192.168.1.*的IP访问。4. 让host-manager可以从外网访问,host-manager默认只可以本机访问,需要修改“tomcathomewebappshost-managerMETA-INF”里“context.xml”文件,修改allow属性值允许其他地址可以访问:<Context antiResourceLocking="false" privileged="true" > <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="^.*$" /></Context>
前言:Options指令是Apache配置文件中一个比较常见也比较重要的指令,Options指令可以在Apache服务器核心配置(server config)、虚拟主机配置(virtual host)、特定目录配置(directory)以及.htaccess文件中使用。Options指令的主要作用?控制特定目录将启用哪些服务器特性。Options指令常见的配置示例代码如下:<Directory "/home/www"> #指定根目录/home/www启用Indexes、FollowSymLinks两种特性 Options Indexes FollowSymLinks AllowOverride all Require all granted</Directory> Options服务器特性Options指令的完整语法为:Options [+|-]option [[+|-]option];简而言之,Options指令后可以附加指定多种服务器特性,特性选项之间以空格分隔。下面我们来看看Options指令后可以附加的特性选项的具体作用及含义(Apache配置中的内容均不区分大小写): 1、All表示除MultiViews之外的所有特性(这也是Options指令的默认设置) 2、None表示不启用任何的服务器特性 3、FollowSymLinks服务器允许在此目录中使用符号连接(如果该配置选项位于配置段中,将会被忽略),意思是:允许网站目录里的链接文件链接到首页目录以外的文件。举例来说,如果你把首页目录设置为/var/www/html,那么你的网页程序最多只能访问到/var/www/html目录,上层目录是不可见的。但是可以通过链接把文件链接到/var/www/html目录以外的文件以访问该文件,如果FollowSymLinks被设置的话。4、Indexes如果输入的网址对应服务器上的一个文件目录,而此目录中又没有DirectoryIndex指令(例:DirectoryIndex index.html index.PHP),那么服务器会返回由mod_autoindex模块生成的一个格式化后的目录列表,并列出该目录下的所有文件(如下图) 4、MultiViews允许使用mod_negotiation模块提供内容协商的”多重视图”。简而言之,如果客户端请求的路径可能对应多种类型的文件,那么服务器将根据客户端请求的具体情况自动选择一个最匹配客户端要求的文件。例如,在服务器站点的file文件夹下中在名为hello.jpg和hello.html的两个文件,此时用户输入Http://localhost/file/hello,如果在file文件夹下并没有hello子目录,那么服务器将会尝试在file文件夹下查找形如hello.*的文件,然后根据用户请求的具体情况返回最匹配要求的hello.jpg或者hello.html 5、SymLinksIfOwnerMatch服务器仅在符号连接与目标文件或目录的所有者具有相同的用户ID时才使用它。简而言之,只有当符号连接和符号连接指向的目标文件或目录的所有者是同一用户时,才会使用符号连接(如果该配置选项位于配置段?,将会被忽略) 6、ExecCGI允许使用mod_cgi模块执行CGI脚本 7、Includes允许?用mod_include模块提供的服务器端包含功能,例如让apache支持ssi。 8、IncludesNOEXEC允许服务器端包含,但禁用”#exec cmd”和”#exec cgi”。但仍可以从ScriptAlias目录使用”#include virtual”虚拟CGI脚本 注意此外,比较细心的读者应该注意到,Options指令语法允许在配置选项前加上符号”+”或者”-“,那么这到底是什么意思呢?实际上,Apache允许在一个目录配置中设置多个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两种特性 备注1:混合使用前面带”+”、”-“和前面不带”+”、”-“的同一可选项,可能会导致出现意料之外的结果 ;备注2:使用-IncludesNOEXEC或-Includes时,不论前面如何设置,都会完全禁用服务器端包含。
什么是shtml? 使用SSI(Server Side Include)的html文件扩展名,SSI(Server Side Include),通常称为"服务器端嵌入"或者叫"服务器端包含",是一种类似于ASP的基于服务器的网页制作技术。默认扩展名是 .stm、.shtm 和 .shtml。 什么是SSI? SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思。从技术角度上说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针。SSI具有强大的功能,只要使用一条简单的SSI命令就可以实现整个网站的内容更新,时间和日期的动态显示,以及执行shell和CGI脚本程序等复杂的功能。网站维护常常碰到的一个问题是,网站的结构已经固定,却为了更新一点内容而不得不重做一大批网页。SSI提供了一种简单、有效的方法来解决这一问题,它将一个网站的基本结构放在几个简单的HTML文件中(模板),以后我们要做的只是将文本传到服务器,让程序按照模板自动生成网页,从而使管理大型网站变得容易 。 如何配置Apache支持SSI? Apache默认是不支持SSI的,需要我们更改httpd.conf来进行配置。我这里以windows平台的Apache 2.0.x为例,打开conf目录下的httpd.conf文件,搜索“AddType text/html .shtml”,找到: # AddType text/html .shtml # AddOutputFilter INCLUDES .shtml 把这两行前面的#去掉 ,然后搜索“Options Indexes FollowSymLinks” ,在搜索到的那一行后面添加“ Includes” ,即将该行改变为:Options Indexes FollowSymLinks Includes 熟悉apache manual的可能会觉得比较容易,保存httpd.conf,重起apache即可 ,到此我们就完成了对Apache SSI的设置。 验证SSI配置成功 在服务器目录上新建文件ssitest.shtml,文件内容为:<!--#echo var="DATE_LOCAL" --> echo元素仅仅是反馈一个变量的值。标准变量有许多,其中包含对CGI程序有效的所有的环境变量。另外,你也可以用set元素定义你的专用变量。 打开得到如下内容 Tuesday, 26-Aug-2008 10:25:53 中国标准时间 表示配置SSI成功,如果没有类似输出,请检查APACHE版本或者配置是否正确。 另外的例子: 如果要包含一个标准页脚,假设页脚内容如下,命名为footer.html:<div style="border:1px solid #333;background:lightyellow;padding:10px;font-size:12px"> Copyright rabbitlxb,All rights reserved. </div> 在ssitest.shtml文件中使用以下语句 <!--#include virtual="footer.html" --> 显示结果如下图可以看到,footer.html的内容被引入到ssitest.html中了。
register_globals是php.ini里的一个配置,这个配置影响到php如何接收传递过来的参数,如果你的问题是:为什么我的表单无法传递数据?为什么我的程序无法得到传递过来的变量?等等,那么你需要仔细的阅读以下的内容。 register_globals的值可以设置为:On或者Off,我们举一段代码来分别描述它们的不同。 <form name="frmTest" id="frmTest" action="URL"> <input type="text" name="user_name" id="user_name"> <input type="password" name="user_pass" id="user_pass"> <input type="submit" value="login"> </form> 当register_globals=Off的时候,下一个程序接收的时候应该用$_GET['user_name']和$_GET['user_pass']来接受传递过来的值。(注:当<form>的method属性为post的时候应该用$_POST['user_name']和$_POST['user_pass'])。当register_globals=On的时候,下一个程序可以直接使用$user_name和$user_pass来接受值。 顾名思义,register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。所以,碰到上边那些无法得到值的问题的朋友应该首先检查一下你的register_globals的设置和你获取值的方法是否匹配。(查看可以用phpinfo()函数或者直接查看php.ini)。那我们为什么要使用Off呢?原因有2:1、php以后的新版本默认都用Off,虽然你可以设置它为On,但是当你无法控制服务器的时候,你的代码的兼容性就成为一个大问题,所以,你最好从现在就开始用Off的风格开始编程。2、这里有两篇文章介绍为什么要Off而不用On http://www.landui.com/forum/gshowflat.php?Cat=&Board=php3&Number=292803&page=0&view=collapsed&sb=5&o=all&fpart= http://www.php.net/manual/en/security.registerglobals.php 现在还有一个问题就是,以前用On风格写的大量脚本怎么办? 如果你以前的脚本规划得好,有个公共包含文件,比如config.inc.php一类的文件,在这个文件里加上以下的代码来模拟一下(这个代码不保证100%可以解决你的问题,因为我没有大量测试,但是我觉得效果不错)。另外,这个帖子里的解决方法也可以参考一下(http://www.chinaunix.net/forum/viewtopic.php?t=159284)。 <?php if ( !ini_get('register_globals') ) { extract($_POST); extract($_GET); extract($_SERVER); extract($_FILES); extract($_ENV); extract($_COOKIE); if ( isset($_SESSION) ) { extract($_SESSION); } } ?> register_globals = Off的情况不仅仅影响到如何获取从<form>、url传递过来的数据,也影响到session、cookie,对应的,得到session、cookie的方式应该为:$_SESSION[]、$_COOKIE。同时对于session的处理也有一些改变,比如,session_register()没有必要而且失效,具体的变化,请查看php manual里的Session handling functions。$_REQUEST中间的内容实际上还是来源于$_GET $_POST $_COOKIE,缺点是无法判断变量到底来自于get post 还是cookie,对要求比较严格的场合不适用。php manual写到:Variables provided to the script via the GET, POST, and COOKIE input mechanisms, and which therefore cannot be trusted. The presence and order of variable inclusion in this array is defined according to the PHP variables_order configuration directive.
截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在维护 [注] 的 PHP5.2, 其余的一半用户在使用 PHP5.3 [注].因为 PHP 那“集百家之长”的蛋疼语法,加?社区氛围不好,很多人对新版本,新特征并无兴趣。本文将会介绍自 PHP5.2 起,直至 PHP5.6 中增加的新特征。? PHP5.2 以前:autoload, PDO 和 MySQLi, 类型约束? PHP5.2:JSON 支持? PHP5.3:弃用的功能,匿名函数,新增魔术方法,命名空间,后期静态绑定,Heredoc 和Nowdoc, const, 三元运算符,Phar? PHP5.4:Short Open Tag, 数组简写形式,Traits, 内置 Web 服务器,细节修改? PHP5.5:yield, list() 用于 foreach, 细节修改? PHP5.6: 常量增强,可变函数参数,命名空间增强注:已于2011年1月停止支持: http://www.php.net/eol.php注:http://w3techs.com/technologies/details/pl-php/5/all PHP5.2以前(2006前)顺便介绍一下 PHP5.2 已经出现但值得介绍的特征。 autoload大家可能都知道 __autoload() 函数,如果定义了该函数,那么当在代码中使用一个未定义的类的时候,该函数就会被调用,你可以在该函数中加载相应的类实现文件,如:function __autoload($classname) { require_once("{$classname}.php") ;}但该函数已经不被建议使用,原因是一个项目中仅能有一个这样的 __autoload() 函数,因为 PHP 不允许函数重名。但当你使用一些类库的时候,难免会出现多个 autoload 函数的需要,于是 spl_autoload_register() 取而代之:spl_autoload_register(function($classname) { require_once("{$classname}.php") });spl_autoload_register() 会将一个函数注册到 autoload 函数列表中,当出现未定义的类的时候,SPL [注] 会按照注册的倒序逐个调用被注册的 autoload 函数,这意味着你可以使用 spl_autoload_register() 注册多个 autoload 函数.注:SPL: Standard PHP Library, 标准 PHP 库, 被设计用来解决一些经典问题(如数据结构). PDO 和 MySQLi即 PHP Data Object, PHP 数据对象,这是 PHP 的新式数据库访问接口。按照传统的风格,访问 MySQL 数据库应该是这样子:// 连接到服务器,选择数据库$conn = mysql_connect("localhost", "user", "password");mysql_select_db("database"); // 执行 SQL 查询 $type = $_POST['type'];$sql = "select * from `table` where `type` = {$type}";$result = mysql_query($sql); // 打印结果 while ($row = mysql_fetch_array($result, MYSQL_ASSOC)){ foreach($row as $k => $v) print "{$k}: {$v} ";} // 释放结果集,关闭连接 mysql_free_result($result);mysql_close($conn);为了能够让代码实现数据库无关,即一段代码同时适用于多种数据库(例如以上代码仅仅适用于MySQL),PHP 官方设计了 PDO.除此之外,PDO 还提供了更多功能,比如:? 面向对象风格的接口? SQL预编译(prepare), 占位符语法? 更高的执行效率,作为官方推荐,有特别的性能优化? 支持大部分SQL数据库,更换数据库无需改动代码上面的代码用 PDO 实现将会是这样:// 连接到数据库$conn = new PDO("mysql:host=localhost;dbname=database", "user", "password"); // 预编译SQL, 绑定参数 $query = $conn -> prepare("select * from `table` where `type` = :type");$query -> bindParam("type", $_POST['type']); // 执行查询并打印结果 foreach($query -> execute() as $row){ foreach($row as $k => $v) print "{$k}: {$v} ";} PDO 是官方推荐的,更为通用的数据库访问方式,如果你没有特殊需求,那么你最好学习和使用 PDO.但如果你需要使用 MySQL 所特有的高级功能,那么你可能需要尝试一下 MySQLi, 因为 PDO 为了能够同时在多种数据库上使用,不会包含那些 MySQL 独有的功能。MySQLi 是 MySQL 的增强接口,同时提供面向过程和面向对象接口,也是目前推荐的 MySQL 驱动,旧的C风格 MySQL 接口将会在今后被默认关闭。MySQLi 的用法和以上两段代码相比,没有太多新概念,在此不再给出示例,可以参见 PHP 官网文档 [注]。注:http://www.php.net/manual/en/mysqli.quickstart.php 类?约束通过类型约束可以限制参数的类型,不过这一机制并不完善,目前仅适用于类和 callable(可执行类型) 以及 array(数组), 不适用于 string 和 int.// 限制第一个参数为 MyClass, 第二个参数为可执行类型,第三个参数为数组function MyFunction(MyClass $a, callable $b, array $c) // ...{} PHP5.2(2006-2011) JSON 支持包括 json_encode(), json_decode() 等函数,JSON 算是在 Web 领域非常常用的数据交换格式,可以被 JS 直接支持,JSON 实际上是 JS 语法的一部分。JSON 系列函数,可以将 PHP 中的数组结构与 JSON 字符串进行转换:$array = ["key" => "value", "array" => [1, 2, 3, 4]];$json = json_encode($array);echo "{$json} ";$object = json_decode($json);print_r($object);输出:{"key":"value","array":[1,2,3,4]} stdClass Object ( [key] => value [array] => Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) )值得注意的是 json_decode() 默认会返回一个对象而非数组,如果需要返回数组需要将第二个参数设置为 true. PHP5.3(2009-2012)PHP5.3 算是一个非常大的更新,新增了大量新特征,同时也做了一些不向下兼容的修改。 弃用的功能以下几个功能被弃用,若在配置文件中启用,则 PHP 会在运行时发出警告。 Register Globals这是 php.ini 中的一个选项(register_globals), 开启后会将所有表单变量($_GET和$_POST)注册为全局变量.看下面的例子:if(isAuth()) $authorized = true; if($authorized) include("page.php");这段代码在通过验证时,将 $authorized 设置为 true. 然后根据 $authorized 的值来决定是否显示页面.但由于并没有事先把 $authorized 初始化为 false, 当 register_globals 打开时,可能访问 /auth.php?authorized=1 来?义该变量值,绕过身份验证。该特征属于历史遗留问题,在 PHP4.2 中被默认关闭,在 PHP5.4 中被移除。 Magic Quotes对应 php.ini 中的选项 magic_quotes_gpc, 这个特征同样属于历史遗留问题,已经在 PHP5.4 中移除。该特征会将所有用户输入进行转义,这看上去不错,在第一章我们提到过要对用户输入进行转义。但是 PHP 并不知道哪些输入会进入 SQL , 哪些输入会进入 Shell, 哪些输入会被显示为 HTML, 所以很多时候这种转义会引起混乱。 Safe Mode很多虚拟主机提供商使用 Safe Mode 来隔离多个用户,但 Safe Mode 存在诸多问题,例如某些扩展并不按照 Safe Mode 来进行权限控制。PHP官方推荐使用操作系统的机制来进行权限隔离,让Web服务器以不同的用户权限来运行PHP解释器,请参见第一章中的最小权限原则. 匿名函数也叫闭包(Closures), 经常被用来临时性地创建一个无名函数,用于回调函数等用途。$func = function($arg) { print $arg; }; $func("Hello World");以上代码定义了一个匿名函数,并赋值给了 $func.可以看到定义匿名函数依旧使用 function 关键字,只不过省略了函数名,直接是参数列表。然后我们又调用了 $func 所储存的匿名函数。匿名函数还可以用 use 关键字来捕捉外部变量:function arrayPlus($array, $num){ array_walk($array, function(&$v) use($num) { $v += $num; } );} 上面的代码定义了一个 arrayPlus() 函数(这不是匿名函数), 它会将一个数组($array)中的每一项,加上一个指定的数字($num).在 arrayPlus() 的实现中,我们使用了 array_walk() 函数,它会为一个数组的每一项执行一个回调函数,即我们定义的匿名函数。在匿名函数的参数列表后,我们用 use 关键字将匿名函数外的 $num 捕捉到了函数内,以便知道到底应该加上多少。 魔术方法:__invoke(), __callStatic()PHP 的面向对象体系中,提供了若干“魔术方法”,用于实现类似其他语言中的“重载”,如在访问不存在的属性、方法时触发某个魔术方法。随着匿名函数的加入,PHP 引入了一个新的魔术方法 __invoke().该魔术方法会在将一个对象作为函数?用时被调用:class A{ public function __invoke($str) { print "A::__invoke(): {$str}"; } } $a = new A;$a("Hello World");输出毫无疑问是:A::__invoke(): Hello World__callStatic() 则会在调用一个不存在的静态方法时被调用。 命名空间PHP的命名空间有着前无古人后无来者的无比蛋疼的语法:<?php // 命名?间的分隔符是反斜杠,该声明语句必须在文件第一行。 // 命名空间中可以包含任意代码,但只有 **类, 函数, 常量** 受命名空间影响。 namespace XXOOTest; // 该类的完整限定名是 XXOOTestA , 其中第一个反斜杠表示全局命名空间。 class A{} // 你还可以在已经文件中定义第二个命名空间,接下来的代码将都位于 OtherTest2 . namespace OtherTest2; // 实例化来自其他命名空间的对象: $a = new XXOOTestA; class B{} // 你还可以用花括号定义第三个命名空间 namespace Other { // 实例化来自子命名空间的对象: $b = new Test2B; // 导入来自其他命名空间的名称,并重命名, // 注意只能导入类,不能用于函数和常量。 use XXOOTestA as ClassA }更多有关命名空间的语法介绍请参见官网 [注].命名空间时常和 autoload 一同使用,用于自动加载类实现文件:spl_autoload_register( function ($class) { spl_autoload(str_replace("\", "/", $class)); } );当你实例化一个类 XXOOTestA 的时候,这个类的完整限定名会被传递给 autoload 函数,autoload 函数将类名中的命名空间分隔符(反斜杠)替换为斜杠,并包含对应文件。这样可以实现类定义文件分级储存,按需自动加载。注:http://www.php.net/manual/zh/language.namespaces.php 后期静态绑定PHP 的 OPP 机制,具有继承和类似虚函数的功能,例如如下的代码:class A{ public function callFuncXXOO() { print $this - > funcXXOO(); } public function funcXXOO() { return "A::funcXXOO()"; } } class B extends A{ public function funcXXOO() { return "B::funcXXOO"; } } $b = new B;$b ->callFuncXXOO();输出是:B::funcXXOO可以看到,当在 A 中使用 $this->funcXXOO() 时,体现了“虚函数”的机制,实际调用的是 B::funcXXOO().然而如果将所有函数都改为静态函数:class A{ static public function callFuncXXOO() { print self :: funcXXOO(); } static public function funcXXOO() { return "A::funcXXOO()"; } } class B extends A{ static public function funcXXOO() { return "B::funcXXOO"; } } $b = new B;$b - >callFuncXXOO();情况就没这么乐观了,输出是:A::funcXXOO()这是因为 self 的语义本来就是“当前类”,所以 PHP5.3 给 static 关键字赋予了一个新功能:后期静态绑定:class A { static public function callFuncXXOO() { print static::funcXXOO(); } // ... } // ...这样就会像预期一样输出了:B::funcXXOO Heredoc 和 NowdocPHP5.3 对 Heredoc 以及 Nowdoc 进行了一些改进,它们都用于在 PHP 代码中嵌入大段字符串。Heredoc 的行为类似于一个双引号字符串:$name = "MyName"; echo <<< TEXT My name is "{$name}". TEXT;Heredoc 以三个左尖括号开始,后面跟一个标识符(TEXT), 直到一个同样的顶格的标识符(不能缩进)结束。就像双引号字符串一样,其中可以嵌入变量。Heredoc 还可以用于函数参数,以及类成员初始化:var_dump(<<<EOD Hello World EOD ); class A { const xx = <<< EOD Hello World EOD; public $oo = <<< EOD Hello World EOD; }Nowdoc 的行为像一个单引号字符串,不能在其中嵌入变量,和 Heredoc 唯?的区别就是,三个左尖括号后的标识符要以单引号括起来:$name = "MyName"; echo <<< 'TEXT' My name is "{$name}". TEXT;输出:My name is "{$name}". 用 const 定义常量PHP5.3 起同时支持在全局命名空间和类中使用 const 定义常量。旧式风格:define("XOOO", "Value");新式风格:const XXOO = "Value";const 形式仅适用于常量,不适用于运行时才能求值的表达式:// 正确 const XXOO = 1234; // 错误 const XXOO = 2 * 617; 三元运算符简写形式旧式风格:echo $a ? $a : "No Value";可简写成:echo $a ?: "No Value";即如果省略三元运算符的第二个部分,会默认用第一个部分代替。 PharPhar即PHP Archive, 起初只是Pear中的一个库而已,后来在PHP5.3被重?编写成C扩展并内置到 PHP 中。Phar用来将多个 .php 脚本打包(也可以打包其他文件)成一个 .phar 的压缩文件(通常是ZIP格式)。目的在于模仿 Java 的 .jar, 不对,目的是为了让发布PHP应用程序更加方便。同时还提供了数字签名验证等功能。.phar 文件可以像 .php 文件一样,被PHP引擎解释执行,同时你还可以写出这样的代码来包含(require) .phar 中的代码:require("xxoo.phar"); require("phar://xxoo.phar/xo/ox.php");更多信息请参见官网 [注].注:http://www.php.net/manual/zh/phar.using.intro.php PHP5.4(2012-2013) Short Open TagShort Open Tag 自 PHP5.4 起总是可用。在这里集中讲一下有关 PHP 起止标签的问题。即:<?php // Code... ?>通常就是上面的形式,除此之外还有一种简写形式:<? /* Code... */ ?>还可以把<?php echo $xxoo;?>简写成:<?= $xxoo;?>这种简?形式被称为 Short Open Tag, 在 PHP5.3 起被默认开启,在 PHP5.4 起总是可用。使用这种简写形式在 HTML 中嵌入 PHP 变量将会非常方便。对于纯 PHP 文件(如类实现文件), PHP 官方建议顶格写起始标记,同时 省略 结束标记。这样可以确保整个 PHP 文件都是 PHP 代码,没有任何输出,否则当你包含该文件后,设置 Header 和 Cookie 时会遇到一些麻烦 [注].注:Header 和 Cookie 必须在输出任何内容之前被发送。 数组简写形式这是非常方便的一项特征!// 原来的数组写法$arr = array("key" => "value", "key2" => "value2"); // 简写形式 $arr = ["key" => "value", "key2" => "value2"]; Traits所谓Traits就是“构件”,是用来替代继承的一种机制。PHP中无法进行多重继承,但一个类可以包含多个Traits.// Traits不能被单独实例化,只能被类所包含trait SayWorld{ public function sayHello() { echo 'World!'; } } class MyHelloWorld // 将SayWorld中的成员包含进来{ use SayWorld;} $xxoo = new MyHelloWorld(); // sayHello() 函数是来自 SayWorld 构件的 $xxoo->sayHello();Traits还有很多神奇的功能,比如包含多个Traits, 解决冲突,修改访问权限,为函数设置别名等等。Traits中也同样可以包含Traits. 篇幅有限不能逐个举例,详情参见官网 [注].注:http://www.php.net/manual/zh/language.oop5.traits.php 内置 Web 服务器PHP从5.4开始内置一个轻量级的Web服务器,不支持并发,定位是用于开发和调试环境。在开发环境使用它的确非常方便。php -S localhost:8000这样就在当前目录建立起了一个Web服务器,你可以通过 http://localhost:8000/ 来访问。其中localhost是监听的ip,8000是监听的端口,可以自行修改。很多应用中,都会进行URL重写,所以PHP提供了一个设置路由脚本的功能:php -S localhost:8000 index.php这样一来,所有的请求都会由index.php来处理。你还可以使用 XDebug 来进行断点调试。 细节修改PHP5.4 新增了动态访问静态方法的方式:$func = "funcXXOO"; A::{$func}();新增在实例化时访问类成员的特征:(new MyClass)->xxoo();新增支持对函数返回数组的成员访问解析(这种写法在之前版本是会报错的):print func()[0]; PHP5.5(2013起) yieldyield关键字用于当函数需要返回一个迭代器的时候, 逐个返回值。function number10() { for($i = 1; $i <= 10; $i += 1) yield $i; }该函数的返回值是一个数组:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list() 用于 foreach可以用 list() 在 foreach 中解析嵌套的数组:$array = [ [1, 2, 3], [4, 5, 6], ];foreach ($array as list($a, $b, $c)) echo "{$a} {$b} {$c} ";结果:1 2 3 4 5 6 细节修改不推荐使用 mysql 函数,推荐使用 PDO 或 MySQLi, 参见前文。不再支持Windows XP.可用 MyClass::class 取到一个类的完整限定名(包括命名空间)。empty() 支持表达式作为参数。try-catch 结?新增 finally 块。 PHP5.6 更好的常量定义常量时允许使用之前定义的常量进行计算:const A = 2;const B = A + 1;class C{ const STR = "hello"; const STR2 = self :: STR + ", world";} 允许常量作为函数参数默认值:function func($arg = C::STR2) 更好的可变函数参数用于代替 func_get_args()function add(...$args){ $result = 0; foreach($args as $arg) $result += $arg; return $result;} 同时可以在调用函数时,把数组展开为函数参数:$arr = [2, 3]; add(1, ...$arr); // 结果为 6 命名空间命名空间支持常量和函数:namespace NameSpace{ const FOO = 42; function f() { echo __FUNCTION__ . " "; } } namespace{ use const NameSpaceFOO; use function NameSpacef; echo FOO . " "; f();}
相信很多人都熟悉iptables,kangle的访问控制理念来自linux的iptables防火墙,kangle拥有功能最小化的匹配模块和标记模块,通过组合,反转等可以实现用户最复杂的需求;最小化的匹配模块和标记模块犹如最小块的积木,独具匠心的玩家,总是能用小积木搭建出千变万化的造形。Kangle的访问控制分为请求控制和回应控制。请求控制在最前面,用户发送请求过来时即进行请求控制。回应控制发生在数据发送给用户之前,即进行回应控制。Kangle详细数据流向图请查看:http://www.kanglesoft.com/thread-7224-1-1.html。每个控制由一张或多张表加一个默认目标组成,其中BEGIN表是系统内建表,所有控制从BEGIN开始。每张表可以定义若干条“链”,在一张表中控制按顺序从上到下对规则链进行匹配。规则链由?个目标和任意个匹配模块和任意个标记模块组成。在表中,用户可以按需要随意添加、删除、编辑或反转规则链。在"请求控制”内有一个系统表:"BEGIN表"。在"回应控制”内有两个系统表"BEGIN表"和"POSTMAP表"。“POSTMAP表”完成url到物理文件的映射。用户使用"POSTMAP表",需要自行创建。例如:对文件进行管理、禁止文件被下载(日志文件不允许被下载)等可用"POSTMAP表"。kangle如果发现用户的请求匹配了一个规则链中的匹配模块,则进入标记模块对请求做简单的处理,之后就按该条规则链指定的目标处理。如果目标是继续,则还要进行下一条规则链处理,否则就返回控制,按控制“目标”进行处理。如果目标是“继续”,则还要进行下一条规则链的处理。如果目标是“默认”,则控制按默认目标处理(默认目标有:拒绝、回写数据、服务器、虚拟主机等)。如果目标是“拒绝”,则将对用户的请求拒绝并发送错误信息给用户,之后中断连接。如果目标是“虚拟主机”,则将对用户请求使用虚拟主机处理。如果目标是“服务器”,则用户使用的是反代。如果目标是“回写数据”,则将对用户的请求拒绝,并发送管理员设定的原始数据给用户。Kangle访问控制设计的优点1、Kangle的访问控制提供了非常开放的用户自定义规则的功能。用户完全可以按需求定制规则;2、Web网?管理,用户无需登录服务器就可以进行操作;3、功能模块的灵活组合,满足用户的各种需求,甚至可以作防攻击系统。例如防CC攻击、防sql注入攻击、防XSS跨站攻击等。Kangle访问控制模块列表及说明请求控制的匹配模块模 块 名 称作 用 域模 块 说 明url请求控制和回应控制匹配用户url网址。网址可以使用正则表达式。reg_path请求控制和回应控制匹配路径。可以使用正则表达式匹配路径。reg_param请求控?和回应控制可用正则表达式进行url参数匹配path请求控制和回应控制匹配路径dst_port请求控制和回应控制匹配目标端口meth请求控制和回应控制匹配http请求方法(如get 、 post )file_ext请求控制和回应控制匹配一个或多个文件扩展名host请求控制和回应控制匹配一个或多个主机头wide_host请求控制和回应控制泛域名匹配map_host请求控制和回应控制匹配一个或多个主机头。与“host”的区别:map_host是以文件形式来存放主机头进行匹配header请求控制和回应控制匹配http头self请求控制和回应控制匹配当前连接的服务器ipsefl_port请求控制和回应控制匹配当前连接的服务器端口src请求控制匹配源地址(ip或者ip段)time请求控制匹配当前时间,格式为:“crontab”ssl_serial请求控制匹配证书序列号auth_user请求控制匹配http论证的用户referer请求控制url来源请求控制的标记模块模 块 名 称作 用 域模 块 说 明speed_limit请求控制限速标记gspeed_limit请求控制分组限速flag请求控制对用户请求作不缓存、不过滤内容及不防cc攻击标记rewrite请求控制url重写redirect请求控制url重定向auth请求控制http认证host_rewrite请求控制主机重写 回应控制的匹配模块模 块 名 称作 用 域模 块 说 明url请求控制和回应控制匹配用户url网址。网址可以使用正则表达式。reg_path请求控制和回应控制匹配路径。可以使用正则表达式匹配路径。reg_param请求控制和回应控制可用正则表达式进行参数匹配path请求控制和回应控制匹配路径dst_port请求控制和回应控制匹配目标端口meth请求控制和回应控制匹配http请求方法(如get 、 post )file_ext请求控制和回应控制匹配一个或多个文件扩展名host请求控制和回应控制匹配一个或多个主机头wide_host请求控制和回应控制泛域名匹配map_host请求控制和回应控制匹配一个或多个主机头。与“host”的区别:map_host是以文件形式来存放主机头进行匹配header请求控制和回应控制匹配http头self请求控制和回应控制匹配当前连接的服务器ipsefl_port请求控制和回应控制匹配当前连接的服务器端口file回应控制匹配一个或多个文件filename回应控制匹配一个或多个文件名dir回应控制匹配多个目录下的文件。按目录匹配reg_file回应控制匹配一个或多个文件。可用正则表达式表示。reg_filename回应控制匹配一个或多个文件名。可用正则表达式表示。content_length回应控制配置内容大小回应控制的标记模块模 块 名 称作 用 域模 块 说 明cache_control回应控制缓存标记content回应控制内容过滤(可以使用正则表达式进行内容过滤)response_flag回应控制对回应给用户的请求作标记add_header回应控制增加自定义头
在php的配置文件(php.ini)中有一个short_open_tag的值,开启以后可以使用PHP的段标签:(<? ?>)。同时,只有开启这个才可以使用 <?= 以代替 <? echo 。在CodeIgniter的视频教程中就是用的这种方式。但是这个短标签是不推荐的,使用<?php ?>才是规范的方法。只是因为这种短标签使用的时间比较长,这种特性才被保存了下来。
以下的文章主要介绍的是MySQL数据类型,MySQL数据库中的5种数据类型是:字符型,文本型,数值型,逻辑型与日期型,以下就是文章的详细内容介绍,希望在你今后的学习中会有所帮助。MySQL数据类型之一字符型VARCHAR VS CHARVARCHAR型和CHAR型数据的这个差别是细微的,但是非常重要。他们都是用来储存字符串长度小于255的字符。假如你向一个长度为四十个字符的VARCHAR型字段中输入数据Bill Gates。当你以后从这个字段中取出此数据时,你取出的数据其长度为十个字符——字符串Bill Gates的长度。 现在假如你把字符串输入一个长度为四十个字符的CHAR型字段中,那么当你取出数据时,所取出的数据长度将是四十个字符。字符串的后面会被附加多余的空格。当你建立自己的站点时,你会发现使用VARCHAR型字段要比CHAR型字段方便的多。使用VARCHAR型字段时,你不需要为剪掉你数据中多余的空格而操心。VARCHAR型字段的另一个突出的好处是它可以比CHAR型字段占用更少的内存和硬盘空间。当你的数据库很大时,这种内存和磁盘空间的节省会变得非常重要。MySQL数据类型之二文本型TEXT使用文本型数据,你可以存放超过二十亿个字符的字符串。当你需要存储大串的字符时,应该使用文本型数据。注意文本型数据没有长度,而上一节中所讲的字符型数据是有长度的。一个文本型字段中的数据通常要么为空,要么很大。当你从HTML form的多行文本编辑框(TEXTAREA)中收集数据时,你应该把收集的信息存储于文本型字段中。但是,无论何时,只要你能避免使用文本型字段,你就应该不适?它。文本型字段既大且慢,滥用文本型字段会使服务器速度变慢。文本型字段还会吃掉大量的磁盘空间。一旦你向文本型字段中输入了任何数据(甚至是空值),就会有2K的空间被自动分配给该数据。除非删除该记录,否则你无法收回这部分存储空间。MySQL数据类型之三数值型SQL支持许多种不同的数值型数据。你可以存储整数 INT 、小数 NUMERIC、和钱数 MONEY。INT VS SMALLINT VS TINYINT他们的区别只是字符长度:INT型数据的表数范围是从-2,147,483,647到2,147,483,647的整数。SMALLINT 型数据可以存储从-32768到32768的整数。TINYINT 型的字段只能存储从0到255的整数,不能用来储存负数。通常,为了节省空间,应该尽可能的使用最小的整型数据。一个TINYINT型数据只占用一个字节;一个INT型数据占用四个字节。这看起来似乎差别不大,但是在比较大的表中,字节数的增长是很快的。另一方面,一旦你已经创建了一个字段,要修改它是很困难的。因此,为安全起见,你应该预测以下,一个字段所需要存储的数值最大有可能是多大,然后选择适当的数据类型。MUNERIC为了能对字段所存放的数据有更多的控制,你可以使用NUMERIC型数据来同时表示一个数的整数部分和小数部分。NUMERIC型数据使你能表示非常大的数——比INT型数据要大得多。一个NUMERIC型字段可以存储从-1038到1038范围内的数。NUMERIC型数据还使你能表示有小数部分的数。例如,你可以在NUMERIC型字段中存储小数3.14。当定义一个NUMERIC型字段时,你需要同时指定整数部分的大小和小数部分的大小。如:MUNERIC(23,0)。一个 NUMERIC型数据的整数部分最大只能有28位,小数部分的位数必须小于或等于整数部分的位数,小数部分可以是零。MONEY VS SMALLMONEY你可以使用 INT型或NUMERIC型数据来存储钱数。但是,专门有另外两种数据类型用于此目的。如果你希望你的网点能挣很多钱,你可以使用MONEY型数据。如果你?野心不大,你可以使用SMALLMONEY型数据。MONEY型数据可以存储从-922,337,203,685,477.5808到922,337,203,685,477.5807的钱数。如果你需要存储比这还大的金额,你可以使用NUMERIC型数据。SMALLMONEY型数据只能存储从-214,748.3648到214,748.3647 的钱数。同样,如果可以的话,你应该用SMALLMONEY型来代替MONEY型数据,以节省空间。MySQL数据类型之四逻辑型BIT如果你使用复选框( CHECKBOX)从网页中搜集信息,你可以把此信息存储在BIT型字段中。BIT型字段只能取两个值:0或1。当心,在你创建好一个表之后,你不能向表中添加 BIT型字段。如果你打算在一个表中包含BIT型字段,你必须在创建表时完成。MySQL数据类型之五日期型DATETIME VS SMALLDATETIME一个 DATETIME型的字段可以存储的日期范围是从1753年1月1日第一毫秒到9999年12月31日最后一毫秒。如果你不需要覆盖这么大范围的日期和时间,你可以使用SMALLDATETIME型数据。它与DATETIME型数据同样使用,只不过它能表示的日期和时间范围比DATETIME型数据小,而且不如DATETIME型数据精确。一个SMALLDATETIME型的字段能够存储从1900年1月1日到2079年6月6日的日期,它只能精确到秒。DATETIME型字段在你输入日期和时间之前并不包含实际的数据,认识这一点是重要的。
1.MySQL无法重启问题解决Warning: World-writable config file ‘/etc/my.cnf’ is ignored原因:今天帮朋友维护服务器,在关闭数据库的命令发现mysql关不了,提示Warning: World-writable config file '/etc/my.cnf' is ignored ,大概意思是权限全局可写,任何一个用户都可以写。mysql担心这种文件被其他用户恶意修改,所以忽略掉这个配置文件。这样mysql无法关闭。[root@ttlsa ~]# service mysqld stop Warning: World-writable config file '/etc/my.cnf' is ignored Warning: World-writable config file '/etc/my.cnf' is ignored MySQL manager or server PID file could not be found![FAILED] 查看my.cnf的权限[root@ttlsa ~]# ls -l /etc/my.cnf -rwxrwxrwx 1 root root 4878 Jul 30 11:31 /etc/my.cnf 权限777,任何一个用户都可以改my.cnf,存在很大的安全隐患.解决方案:修复MySQL问题[root@ttlsa ~]# chmod 644 /etc/my.cnf my.cnf设置为用户可读写,其他用户不可写. 2.Can't connect to MySQL server on 'localhost' (10061)原因:不能连接到 localhost 上的mysql解决方案:这说明“localhost”计算机是存在的,但在这台机器上却没提供MySQL服务。需要启动这台机器上的MySQL服务,如果机子负载太高没空相应请求也会产生这个错误。解决:既然没有启动那就去启动这台机子的mysql。如果启动不成功,多数是因为你的my.ini配置的有问题。重新配置其即可。如果觉得mysql负载异常,可以到mysql/bin 的目录下执行mysqladmin -uroot -p123 processlist来查看mysql当前的进程。 3.Unknown MySQL Server Host 'localhosadst' (11001)原因:未知的MySQL服务器 localhosadst,服务器 localhosasdst 不存在。或者根本无法连接。解决方案:仔细检查自己站点下面的 ./config.inc.php 找到$dbhost重新设置为正确的mysql 服务器地址。 4.Access denied for user: 'roota@localhost' (Using password: YES)原因:用户 roota 访问 localhost 被拒绝(没有允许通过),造成这个错误一般数据库用户名和?码相对mysql服务器不正确。解决方案:仔细检查自己站点下面的 ./config.inc.php 找到$dbuser、$dbpw核实后重新设置保存即可。 5.Access denied for user: 'red@localhost' to database 'newbbs'原因:用户 red 在localhost 服务器上没有权限操作数据库newbbs,这个提示和问题三是不同的。那个是在连接数据库的时候就被阻止了,而这个错误是在对数据库进行操作时引起的。比如在select update等等。这个是因为该用户没有操作数据库相应的权力。比如select 这个操作在mysql.user.Select_priv里记录 Y 可以操作N 不可以操作。解决方案:如果是自己的独立主机那么更新mysql.user 的相应用户记录,比如这里要更新的用户为red 。或者直接修改 ./config.inc.php 为其配置一个具有对数据库操作权限的用户或者通过如下的命令来更新授权grant all privileges on dbname.* to 'user'@'localhost' identified by 'password’提示:更新了mysql库中的记录一定要重启mysql服务器才能使更新生效。 6.No Database Selected原因:产生的原因有两种。config.inc.php 里面$dbname设置的不对。致使数据库根本不存在,所以在 $db->select_db($dbname); 时返回了false和上面问题四是一样的,数据库用户没有select权限,同样会导致这样的错误。当你发现config.inc.php的设置没有任何问题,但还是提示这个错误,那一定就是这种情况了。解决方案:对症下药,打开config.inc.php 找到$dbname核实重新配置并保存同问题四的解决方法。 7.Can't open file: 'xxx_forums.MYI'. (errno: 145)原因:这种情况是不能打开 cdb_forums.MYI 造成的,引起这种情况可能的原因有:1、服务器非正常关机,数据库所在空间已满,或一些其它未知的原因,对数据库表造成了损坏。2、类 unix 操作系统下直接将数据库文件拷贝移动会因为文件?属组问题而产生这个错误。解决方案:1、修复数据表,可以使用下面的两种方式修复数据表:(第一种方法仅适合独立主机用户)1)使用 myisamchk ,MySQL 自带了专门用户数据表检查和修复的工具 —— myisamchk 。更改当前目录到 MySQL/bin 下面,一般情况下只有在这个下面才能运行 myisamchk 命令。常用的修复命令为:myisamchk -r 数据文件目录/数据表名.MYI;2)通过 phpMyAdmin 修复, phpMyAdmin 带有修复数据表的功能,进入到某一个表中后,点击“操作”,在下方的“表维护”中点击“修复表”即可。注意:以上两种修复方式在执行前一定要备份数据库。2、修改文件的属组(仅适合独立主机用户)复制数据库文件的过程中没有将数据库文件设置为 MySQL 运行的帐号可读写(一般适用于 Linux 和 FreeBSD 用户)。 8.Table 'test.xxx_sessions' doesn't exist翻译:xxxxx表不存在原因:在执行sql语句时没有找到表,比如:select * from xxx_members where uid=’XX’ 这里如果表xxx_members不存在于$dbname库里,那么就会提示这个错误。具体可分为以下三种情况来讨论:安装插件或者hack时修改了程序文件,而忘记了对数据库作相应的升级。后台使用了不完全备份,导入数据时没有导入到已经安装了相应版本的论坛的数据库中。解决方案:同样对症下药,不同的原因不同的处理方法。仔细对照插件作者提供的安装说明,把遗漏的对数据库的操作补上,如果仍然不能解决问题,那么应该怀疑该插件的可用性了。去咨询一下插件作者,或者将其卸载。不要张冠李戴,多大的脚就穿多大的鞋。总之使得程序文件和数据库配套即可. 9.Unknown column 'column_name' in 'field list'原因:在执行sql语句是出现了指定表中没有的字段名称,就会出现这个错误。具体导致的原因可分为以下两种安装插件或者hack时修改了程序文件,而忘记了对数据库作相应的升级。程序文件和数据库不配套,比如d2.5的数据库配置给d4.1的程序来用肯定会出现这个错误。解决方案:导致的原因和问题八的1和 3是相同的,所以解决方法也一样。 10.You have an error in your SQL syntax原因:论坛标准的程序是没有sql语法错误的。所以造成这个错误的原因一般就两类:安装插件或擅自修改程序。不同的数据库版本数据库导出导入,比如MySQL4.1的数据在导出的语句包含了MySQL4.0没有的功能,像字符集的设定,这时如果将这些sql导入到MySQL4.0的时候就会产生sql语法错误。解决方案:仔细检查看到底是哪里的错误,将其修正,实在不行就用标准程序把出错的程序替换。在数据库备份的时候要留意,如果不打算倒入到其他版本的mysql中则不用特殊考虑,反之要特殊的设定。使用DZ4.1的后台数据备份,可以按照提示去设定想要的格?。独立主机的也可以在到处的时候将其导出为mysql4.0的格式。mysqldump -uroot -p --default-character-set=latin1 --set-charset=gbk --skip-opt databse > test.sql 11.Duplicate entry 'xxx' for key 1翻译:插入 xxx 使索引1重复原因:索引如果是primary unique这两两种,那么数据表的数据对应的这个字段就必须保证其每条记录的唯一性。否则就会产生这个错误。一般发生在对数据库写操作的时候,例如Discuz!4.1论坛程序要求所有会员的用户名username必须唯一,即username的索引是 unique,这时如果强行往cdb_members表里插入一个已有的username的记录就会发上这个错误,或者将一条记录的username更新 为已有的一个username。改变表结构的时候也有可能导致这个错误。例如 Discuz!4.0论坛的数据库中cdb_members.username 的索引类型是index这个时候是允许有相同username的记录存在的,在升级到4.1的时候,因为要将username的索引由原来的index变 为unique。如果这时cdb_members里存在有相同的username的记录,那么就会引发这个错误。导出数据据时有时会因为一些原因(作者目前还不清楚)导致同一条记录被重复导出,那么这个备份数据在导入的时候出现这个错误是在所难免的了。修改了auto_increment的值,致使“下一个 Autoindex”为一条已经存在的记录。解决方案:两种思路,一是破坏掉唯一性的索引。二是把重复的数据记录干掉,只保留一条。很显然第一种思路是不可取的。那么按照二的思路我们得出以下几种解决方法,对应上面的i ii iii略,按照错误提示里的信息到数据库中将重复的记录删除,仅保留一条即可。之后继续执行升级操作。这种情况发生的概率很小,可以用文本编辑器打开备份文档,查找重复的信息。将其多余的拿掉,仅保留一条即可。查询出表中auto_increment最大的一条记录,设置auto_incerment比其大一即可。PS:repaire table "表名“,可以暂时解决问题。 12.Duplicate key name 'xxx'翻译:索引名重复原因:要创建的索引已经存在了,就会引发这个错误,这个错误多发生在升级的时候。可能是已经升级过的,重复升级引起的错误。也有可能是之前用户擅自加的索引,刚好与升级文件中的所以相同了。解决方案:看看已经存在的索引和要添加的索引是否一样,一样的话可以跳过这条sql语句,如果不一样那么现删除已存在的所以,之后再执行。 13.Duplicate column name 'xxx'翻译:字段名xxx重复原因:添加的字段xxx已经存在,多发生在升级过程中,与问题十二的产生是一样的。解决方案:看一下已经存在的字段是否和将要添加的字段属性完全相同,如果相同则可以跳过不执行这句sql,如果不一样则删除掉这个字段。之后继续执行升级程序。 14.Table 'xxx' already exists翻译:数据表xxx已经存在原因:xxx表已经存在于库中,再次试图创建这个名字的表就会引发这个错误。同样多发生在论坛的升级中。类似于问题十二。解决方案:看看已经存在的表是否和将要创建的表完全一样,一样的话可以跳过不执行这个sql,否则请将存在的表先删除,之后继续执行升级文件。 15.Can't create database 'xxx'. Database exists不能创建数据库xxx,数据库已经存在原因:一个mysql下面的数据库名称必须保证唯一性,否则就会有这个错误。解决方案:把已经存在的数据库改名或者把将要创建的数据库改名,总之不让他们的名称冲突。 16.小结(针对问题 1112131415)此类问题错误提示中都暗藏一个关键词duplicate(重复),那么对于mysql数据库来说什么东西是不能重复的呢?数据库 database同一个数据库下数据表 table同一个数据表下字段 column同一个数据表下索引 key同一个数据表在索引唯一(UNIQUE PRIMARY)的情况下记录中的这些字段不可以重复 17.Unknown system variable 'NAMES'翻译:未知的系统变量NAMES原因:Mysql版本不支持字符集设定,此时强行设定字符集就会出现这个错误。解决方案:将sql语句中的SET NAMES ‘xxx’ 语句去掉 18.Lost connection to MySQL server during query翻译:MySQL服务器失去连接在查询期间原因:远程连接数据库是有时会有这个问题。MySQL服务器在执行一条sql语句的时候失去了连接造成的。解决方案:一般不需要怎么去处理,如果频繁的出现那么考虑改善硬件环境。 19.User 'red' has exceeded the 'max_updates' resource (current value: 500)翻译:msql用户red已经超过了'max_updates'(最大更新次数),'max_questions'(最大查询次数),'max_connections'(最大连接数),当前设定为500原因:在mysql数据库的下有一个库为mysql,它其中?一个表为user这里面的纪录每一条都对应为一个mysql用户的授权。其中字段 max_questions max_updates max_connections分别记录着最大查询次数 最大更新数 最大连接数,当目前的任何一个参数大于任何一个设定的值就会产生这个错误。解决方案:独立主机用户可以直接修改授权表。修改完之后重启mysql或者跟新授权表,进入mysql提示符下执行FLUSH PRIVILEGES;记得后面要有分号’;’,虚拟主机的用户如果总是出现这个问题可找空间商协商解决。 20.Too many connections (1040)链接过多翻译:达到最大连接数原因:连接数超过了mysql设置的值,与max_connections 和wait_timeout 都有关系。wait_timeout的值越大,连接的空闲等待就越长,这样就会造成当前连接数越大。解决方案:1.虚拟主机?户请联系空间商优化 MySQL 服务器的配置;2.独立主机用户请联系服务器管理员优化 MySQL 服务器的配置,可参考:修改 MySQL 配置文件 my.ini 或者 my.cnf 中的参数:max_connections= 1000wait_timeout = 10修改后重启 MySQL ,如果经常性的报此错误,请做一下服务器的整体优化。 21.There is no such grant defined for user '%s' on host '%s'错误编号:1141原因:MySQL 当前用户无权访问数据库。解决方案:1、虚拟主机用户请联系空间商,确认给你提供的帐号是否有授权数据库的权限。2、独立主机用户请联系服务器管理员,确认给您提供的数据库帐号是否有管理此数据库的权限。 22.Error on rename of '%s' to '%s' (errno: %d)error.:1025原因:请检查一下您的程序是否有修改数据库表名的语句。解决方案:1.请检查您的程序中哪些地方需要修改数据库表名;2.如果您的实际应用确实需要修改到数据库表名的话,请联系空间商或者服务器管理员给您开放修改库名的权限和服务器本身是否正常。 23.Error reading file '%s' (errno: %d)error.:1023原因:数据库文件不能被读取。解决方案:1.虚拟主机用户请联系空间商查看数据库是否完好。2.独立主机用户请联系服务器管理员检查一下 MySQL 本身是否正常, MySQL 是否可以读取文件,Linux 用户可以检查一下 MySQL 的数据库文件的属主是否正确以及本身的文件是否损坏。 24.Host '*****' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'error.:1129原因:数据库出现异常,请重启数据库。解决方案:由于存在很多连接错误,主机'****'被屏蔽,虚拟主机用户请联系空间商处理,独立主机用户请联系服务器管理员,在 MySQL 的命令控制台下执行'mysqladmin flush-hosts'解除屏蔽即可,或者重启 MySQL 数据库。 25.dropping database (can't delete '%s', errno: %d)error.:1009原因:不能删除数据库文件,导致删除数据库失败。解决方案:1.检查您使用的数据库管理帐号是否有权限删除数据。2.检查数据库是否存在。 26.Got error 28 from table handlererror.:1030原因:数据库所在磁盘空间已满。解决方案:1.虚拟主机用户请联系空间商增加 MySQL 所在的磁盘空间或者清理一些无用文件;2.独立主机用户请联系服务器管理员增加 MySQL 所在的磁盘空间或者清理一些无用文件。 27.Can't create a new thread; if you are not out of available memory, you can consult the manual for a possible OS-dependent bug。error.:11/35原因:数据库服务器问题,数据库操作无法创建新线程。一般是两个原因:1.服务器系统内存溢出。2.环境软件损坏或系统损坏。解决方案:1.虚拟主机用户请联系下空间商数据库服务器的内存和系统是否正常。2.?立主机用户请联系服务器管理员检查服务器的内存和系统是否正常,如果服务器内存紧张,请检查一下哪些进程消耗了服务器的内存,同时考虑是否增加服务器的内存来提高整个的负载能力。 28.Error: Client does not support authentication protocol requested by server; consider upgrading MySQL clienterror.:1251原因:如果你升级 MySQL 到 4.1 以上版本后遇到以上问题,请先确定你的 MySQL Client ? 4.1 或者更高版本( Windows 下有问题你就直接跳到下面看解决方法了,因为 MySQL 在 Windows 是 client 和 server 一起装上了的)。解决方案:1. Windows 平台主要是改变连接 MySQL 的帐户的加密方式,MySQL 4.1/5.0 是通过 PASSWORD 这种方式加密的。可以通过以下两种方法得到解决:1)mysql->SET PASSWORD FOR 'some_user'@'some_host'=OLD_PASSWord('new_password');2)mysql->update mysql.user SET Password=OLD_PASSWord('new_password') where Host='some_host' AND User='some_user';2. Linux/Unix 平台Linux 平台下首先确定是否安装过 MySQL 的客户端,这个用 rpm 安装很简单,Linux 代码为:rpm -ivh MySQL-client-4.1.15-0.i386.rpm然后在编译 php 的时候要加上:--with-mysql=/your/path/to/mysql一般情况下都可以解决。如果还出现这种错误,可以按照下面的方法来做:mysql->SET PASSWORD FOR 'some_user'@'some_host'=OLD_PASSWord('new_password');mysql->update mysql.user SET Password=OLD_PASSWord('new_password') where Host='some_host' AND User='some_user'; 29.Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'error.:2002原因:出现这个错误一般情况下是因为下面两个原因:1.MySQL 服务器没有开启。2.MySQL 服务器开启了,但不能找到 socket 文件。解决方案:1.虚拟主机用户,请联系空间商确认数据库是否正常启动。2.独立主机用户,请检查一下MySQL服务是否已经开启,没有开启,请启动MySQL服务;如果已经开启,并且是Linux系统,请检查一下MySQL的socket的路径,然后打开config.inc.php找到$dbhost = 'localhost';在 hostname后面加冒号‘:’和 MySQL的socket 的路径。比如MySQL服务器为localhostMySQL的socket的路径为/tmp/mysql.sock那么就改成如下:$dbhost = 'localhost:/temp/mysql.sock'; 30.Can't connect to MySQL server on 'localhost'error.:2003原因:MySQL服务没有启动,一般是在异常的情况下MySQL无法启动导致的,比如无可用的磁盘空间,my.ini里MySQL的basedir路径设置错误等。解决方案:1.检查磁盘空间是否还有剩余可用空间,尽量保持有足够的磁盘空间可用。2.检查 my.ini 里的 basedir 等参数设置是否正确,然后重新启动下 MySQL 服务。 31.Lost connection to MySQL server during queryerror.:2013原因:数据库查询过程中丢失了与 MySQL 服务器的连接。解决方案:1.请确认您的程序中是否有效率很低的程序,比如某些插件,可以卸载掉插件,检查一?服务器是否正常;2.服务器本身资源紧张,虚拟主机用户请联系空间商确认,独立主机用户请联系服务器管理员,检查一下服务器是否正常。 32.Got a packet bigger than 'max_allowed_packet' bytes错误编号:1153原因:调整了 Mantis 的上传附件的大小却没有调整 MySQL 的配置文件。解决方案:1、独立主机用户请按照以下方法调整:查找 MySQL 的配置文件(my.cnf 或者 my.ini),在 [mysqld] 部分添加一句(如果存在,调整其值就可以):max_allowed_packet=10M重启 MySQL 服务就可以了。这里设置的是 10MB。2、虚拟主机用户请联系空间商调整此参数。
MySQL数据库是目前开源应用最大的关系型数据库,有海量的应用将数据存储在MySQL数据库中。存储数据的安?性和可靠性是生产数据库的关注重点。本文分析了目前采用较多的保障MySQL可用性方案。MySQL ReplicationMySQL Replication是MySQL官方提供的主从同步方案,用于将一个MySQL实例的数据,同步到另一个实例中。Replication为保证数据安全做了重要的保证,也是现在运用最广的MySQL容灾方案。Replication用两个或以上的实例搭建了MySQL主?复制集群,提供单点写入,多点读取的服务,实现了读的scale out。图1. MySQL Replication主从复制集群如图一所示,一个主实例(M),三个从实例(S),通过replication,Master生成event的binlog,然后发给slave,Slave将event写入relaylog,然后将其提交到自身数据库中,实现主从数据同步。对于数据库之上的业务层来说,基于MySQL的主?复制集群,单点写入Master,在event同步到Slave后,读逻辑可以从任何一个Slave读取数据,以读写分离的方式,大大降低Master的运行负载,同时提升了Slave的资源利用。对于高可用来说,MySQL Replication有个重要的缺陷:数据复制的时延。在通常情况下,MySQL Replication数据复制是异步的,即是MySQL写binlog后,发送给Slave并不等待Slave返回确认收到,本地事务就提交了。一旦出现网络延迟或中断,数据延迟发送到Slave侧,主从数据就会出现不一致。在这个阶段中,Master一旦宕机,未发送到Slave的数据就丢失了,无法做到数据的高可用。为了解决这个问题,google提供了解决方案:半同步和同步复制。在数据异步复制的基础之上,做了一点修改。半同步复制是Master等待event写入Slave的relay后,再提交本地,保证Slave一定收到了需要同步的数据。同步复制不不仅是要求Slave收到数据,还要求Slave将数据commit到数据库中,从而保证每次的数据写入,主从数据都是一致的。基于半同步和同步复制,MySQL Replication的高可用得到了质的提升,特别是同步复制。基于同步复制的MySQL Replication集群,每个实例读取的数?都是一致的,不会存在Slave幻读。同时,Master宕机后,应用程序切换到任何一个Slave都可以保证读写数据的一致性。但是,同步复制带来了重大的性能下降,这里需要做一个折衷。另外,MySQL Replication的主从切换需要人工介入判断,同时需要Slave的replaylog提交完毕,故障恢复时间会比较长。MySQL FabricMySQL Fabric是MySQL社区提供的管理多个MySQL服务的扩展。高可用是它设计的主要特性之一。Fabric将两个及以上的MySQL实例划分为一个HA Group。其中的一个是主,其余的都是从。HA Group保证访问指定HA Group的数据总是可用的。其基础的数据复制是基于MySQL Replication,然后,Fabric提供了更多的特性:失效检测和恢复:Fabric监控HA Group中的主实例,一旦发现主实例失效,Fabric会从HA Group中剩余的从实例中选择一个,并将其提升为主实例。读写均衡:Fabric可以自动的处理一个HA Group的读写操作,将写操作发送给主实例,而读请求在多个从实例之间做负载均衡。图2. FabricMHAMHA(MySQL-master-ha)是目前广泛使用的MySQL主从复制的高可用方案。MHA设计目标是自动实现主实例宕机后,从机切换为主,并尽量降低切换时延(通常在10-30s内切换完成)。同时,由MHA保证在切换过程中的数据一致性。MHA对MySQL的主从复制集群非常友好,没有对集群做任何侵入性的修改。MHA的一个重点?性是:在主实例宕机后,MHA可以自动的判断主从复制集群中哪个从实例的relaylog是最新的,并将最新从实例的差异log“应用”到其余的从实例中,从而保证每个实例的数据一致。通常情况下,MHA需要10s左右检测主实例异常,并将主实例关闭从而避免脑裂。然后再用10s左右将差异的log event同步,并启用新的Master。整个MHA的RTO时间大约在30s。MySQL ClusterMySQL Cluster是一个高度可扩展的,兼容ACID事务的实时数据库,基于分布式架构不存在单点故障,MySQL Cluster支持自动水平扩容,并能做自动的读写负载均衡。MySQL Cluster使用了一个叫NDB的内存存储引擎来整合多个MySQL实例,提供一个统一的服务集群。如图三所示。图3. MySQL Cluster组成MySQL Cluster由SQL Nodes,DataNodes,和NDB Management Server组成。SQL Nodes是应用程序的接口,像普通的mysqld服务一样,接受用户的SQL输入,执行并返回结果。Data Nodes是数据存储节点,NDB Management Server用来管理集群中的每个node。MySQL Cluster采用了新的数据分片和容错的方式来实现数据安全和高可用。其由Partition,Replica,Data Node,Node Group构成。Partition:NDB一张表的一个数据分片,包含一张表的一部分数据。Replica:一个Partition的拷贝。一个Partition可以有一个或多个Replica,一个Partition的所有Replica数据都是一致的。Data Node:Replica的存储载体,每个Node存储一个或多个Replica。Node Group:一个Data Node的集合。图4. MySQL Cluster数据高可用一个MySQL Cluster有4个Node,被分为了两个Grou。Node1和2归属于Group0,Node3和4归属于Group1,。有一张表被分为4个Partition,并分别有两个Replica。Partition0和Partition2的两个Replica,分别存储在Node1和Node2上,Pratition1和Partition3的两个Replica分别存在Node3和Node4上。这样,对于一张表的一个Partition来说,在整个集群有两份数据,并分布在两个独立的Node上,实现了数据容灾。同时,每次对一个Partition的写操作,都会在两个Replica上呈现,如果Primary Replica异常,那么Backup Replica可以立即提供服务,实现数据的高可用?小结本文分析了目前MySQL使用较多的几种MySQL数据复制和高可用方案,从使用来看,MySQL Replication是使用最为广泛的数据复制方案,因为是MySQL原生支持,针对其在不同场景下的一些缺陷,衍生出了半同步复制,强同步复制等数据高可用的方案。在此基础之上,为了运维方便,MySQL Fabric和MHA应运而生,从不同的方向解决了主从切换时数据一致性问题和流程自动化的问题。此外,随着分布式系统架构和方案的逐步成熟。MySQL Cluster设计了全新的分布式架构,采用多副本,Sharding等特性,支持水平扩展,做到了5个9的数据库服务质量保证。
服务热线:
4006-75-4006(7*24小时在线)
总机直拨:
0871-63886388(工作日9:00-18:00)
售前咨询
售后咨询
备案咨询
电话
二维码
TOP