Mysql: Too many connections in …Session:Failed to write session data(files).两个问题的解决
近日在网上发现了这样一个问题,以前没有碰到过,如下图
问题一
mysql_connect(); too many connections in …connRadio.php错误信息,这个是mysql的运行错误问题,目前这个mysql也就是挂起状态的,这个错误是因为mysql的连接数超过了它设置的最大连接数。整个网站也就处于崩溃状态了。网上查找原因说是my.cnf(windows下为my.ini)文件里面的max_connections设置值太小的问题,直接更改为更大的值,如1000就行了。默认的linux上安装的mysql配置文件里面的max_connections 为100(本人暂未证实,来源于网上)mysql默认的my-medium.cnf,中型服务器配置。
[mysqld] port = 3306 socket = /tmp/mysql.sock skip-locking key_buffer = 160M max_allowed_packet = 1M table_cache = 64 sort_buffer_size = 512K net_buffer_length = 8K read_buffer_size = 256K read_rnd_buffer_size = 512K myisam_sort_buffer_size = 8M max_connections=1000
不过这个也与整体程序有关,很可能是mysql_connect()连接多次创建打开后,并没有使用mysql_close()进行关闭,导致连接越来越多,最后崩溃。上面的修改max_connections值,重启mysql服务器也只是权宜之计。真正需要修改的还有程序代码。目前普遍的开源cms或者blog都没有发现过这样类似的问题,一般对于数据库实例的实现是采用单例模式或者mysql_pconnect()永久连接(通常设计存在于一对一的分布而设计的,如单http服务器对于单mysql服务器,下面附php manual中对数据库永久链接的说明)。
问题二
failed: No space left on device (28) 意思就是说磁盘空间不够用了。。。Failed write to session data(files) session文件不可写,如果没有空间了当然也就不可写了。我们知道php默认的session信息时写在服务器的临时目录中的,如/var/tmp,C:\WINDOWS\Temp,上面的使用的是系统默认的临时文件夹,所以应该不是权限问题导致不可写。至于空间不够用的问题,也可能随着短时间访问量暴增会增加很多session文件。而结合上面的mysql_connect()连接次数过多,出现这样的问题可能是短时间访问量过大导致
session可以通过gc_maxlefttime设置最大的生存周期,而php自身的GC(Garbage Collector)垃圾回收处理方式,防止内存溢出。当一个PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中所有对象同时被销毁。GC进程一般都跟着每起一个SESSION而开始运行的。gc目的是为了在session文件过期以后自动销毁删除这些文件。
引用:http://developer.51cto.com/art/200912/168020.htm
有关详细的session与gc的运行关系
由于PHP的工作机制,它并没有一个daemon线程来定期的扫描Session信息并判断其是否失效,当一个有效的请求发生时,PHP 会根据全局变量 session.gc_probability和session.gc_divisor的值,来决定是否启用一个GC, 在默认情况下,session.gc_probability=1, session.gc_divisor =100也就是说有1%的可能性启动GC(也就是说100个请求中只有一个gc会伴随100个中的某个请求而启动).
PHP垃圾回收机制的工作就是扫描所有的Session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime参数进行比较,如果生存时间超过gc_maxlifetime(默认24分钟),就将该session删除。
但是,如果你Web服务器有多个站点,多个站点时,GC处理session可能会出现意想不到的结果,原因就是:GC在工作时,并不会区分不同站点的session.
那么这个时候怎么解决呢?
1. 修改session.save_path,或使用session_save_path()让每个站点的session保存到一个专用目录,
2. 提供GC的启动率,自然,PHP垃圾回收机制的启动率提高,系统的性能也会相应减低,不推荐。
3. 在代码中判断当前session的生存时间,利用session_destroy()删除.
数据库永久连接
引用至php manual
永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时。PHP 将检查是否已经存在一个(前面已经开启的)相同的永久连接。如果存在,将直接使用这个连接;如果不存在,则建立一个新的连接。所谓“相同”的连接是指用相同的用户名和密码到相同主机的连接。
对 web 服务器的工作和分布负载没有完全理解的读者可能会错误地理解永久连接的作用。特别的,永久连接不会在相同的连接上提供建立“用户会话”的能力,也不提供有效建立事务的能力。实际上,从严格意义上来讲,永久连接不会提供任何非永久连接无法提供的特殊功能。
为什么?
这和 web 服务器工作的方式有关。web 服务器可以用三种方法来利用 PHP 生成 web 页面。
第一种方法是将 PHP 用作一个“外壳”。以这种方法运行,PHP 会为向 web 服务器提出的每个 PHP 页面请求生成并结束一个 PHP 解释器线程。由于该线程会随每个请求的结束而结束,因此任何在这个线程中利用的任何资源(例如指向 SQL 数据库服务器的连接)都会随线程的结束而关闭。在这种情况下,使用永久连接不会获得任何地改变——因为它们根本不是永久的。
第二,也是最常用的方法,是把 PHP 用作多进程 web 服务器的一个模块,这种方法目前只适用于 Apache。对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成 web 页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个永久连接后,所有请求 SQL 服务的后继页面都能够重新使用这个已经建立的 SQL Server 连接。
最后一种方法是将 PHP 用作多线程 web 服务器的一个插件。目前 PHP 4 已经支持 ISAPI、WSAPI 和 NSAPI(在 Windows 环境下),这些使得 PHP 可以被用作诸如 Netscape FastTrack (iPlanet)、Microsoft’s Internet Information Server (IIS) 和 O’Reilly’s WebSite Pro 等多线程 web 服务器的插件。永久连接的行为和前面所描述的多过程模型在本质上是相同的。注意 PHP 3 不支持 SAPI。
如果永久连接并没有任何附加的功能,那么使用它有什么好处?
答案非常简单——效率。当客户端对 SQL 服务器的连接请求非常频繁时,永久连接将更加高效。连接请求频繁的标准取决于很多因素。例如,数据库的种类,数据库服务和 web 服务是否在同一台服务器上,SQL 服务器如何加载负载等。但我们至少知道,当连接请求很频繁时,永久连接将显著的提高效率。它使得每个子进程在其生命周期中只做一次连接操作,而非每次在处理一个页面时都要向 SQL 服务器提出连接请求。这也就是说,每个子进程将对服务器建立各自独立的永久连接。例如,如果有 20 个不同的子进程运行某脚本建立了永久的 SQL 服务器永久连接,那么实际上向该 SQL 服务器建立了 20 个不同的永久连接,每个进程占有一个。
注意,如果永久连接的子进程数目超过了设定的数据库连接数限制,系统将会产生一些缺陷。如果数据库的同时连接数限制为 16,而在繁忙会话的情况下,有 17 个线程试图连接,那么有一个线程将无法连接。如果这个时候,在脚本中出现了使得连接无法关闭的错误(例如无限循环),则该数据库的 16 个连接将迅速地受到影响。请查阅使用的数据库的文档,以获取关于如何处理已放弃的及闲置的连接的方法。
Warning
在使用永久连接时还有一些特别的问题需要注意。例如在永久连接中使用数据表锁时,如果脚本不管什么原因无法释放该数据表锁,其随后使用相同连接的脚本将会被永久的阻塞,使得需要重新启动 httpd 服务或者数据库服务。另外,在使用事务处理时,如果脚本在事务阻塞产生前结束,则该阻塞也会影响到使用相同连接的下一个脚本。不管在什么情况下,都可以通过使用 register_shutdown_function() 函数来注册一个简单的清理函数来打开数据表锁,或者回滚事务。或者更好的处理方法,是不在使用数据表锁或者事务处理的脚本中使用永久连接,这可以从根本上解决这个问题(当然还可以在其它地方使用永久连接)。
以下是一点重要的总结。永久连接是为通常连接建立一对一的分布而设计的。这意味着必须能够保证在将永久连接替换为非永久连接时,脚本的行为不会改变。使用永久连接将(非常)有可能改变脚本的效率,但不改变其行为!
常用的clearfix对于ie8的影响
.clearfix:after { clear: both; visibility: hidden; content: '. '; display: block; height: 0;} /* 加点 与不加点 作用于ie8得区别 */
.clearfix { display: inline-block; }
* html .clearfix { height:1%; } /* 兼容于ie6 或者使用 *zoom: 1; 让ie6自动清除浮动包裹里面的元素 */
如上的clearfix是我常用的清除浮动的代码,用过许多次了,感觉没有什么问题;不过前几天突然发现clearfix在ie8下有特别的显示。demo请点击clearfix_ie8,在firefox、chrome、opera、ie7、ie6都是如下的图形
但是在ie8模式下,你会看到明显的格式区别item之间有大约10px的间隙。
我们知道最初浮动的清除采用的是在浮动的子div同级加空div的方式,即<div style=”clear:both”></div> 这样既可自动撑开父div,达到清除浮动的效果。
而clearfix原理同样如此,after伪类可以在使用clearfix的容器之后新建一个空的容器,这容器高度为0、visibility不可见,clear单独在一行显示,display为块级元素,content包含一个“.”。
after伪类在ie7以上、firefox、chrome、opera等浏览器都支持,但ie6以及ie6内核的其他浏览器都是不支持这个的。所以让ie6支持可以采用
* html .clearfix { height:1%; } /* 兼容于ie6 或者使用 *zoom: 1; 让ie6自动清除浮动包裹里面的元素 */
不过ie8 clearfix多出10px的原因还没说明。我偶然的实验发现,原来问题就在这个content,
content 属性与 :befor 及 :after 伪元素配合使用,来插入生成内容。
该属性用于定义元素之前或之后放置的生成内容。默认地,这往往是行内内容,不过该内容创建的框类型可以用属性 display 控制。
而ie8的10px多出来的,就是content: ‘.’; 这个句点所产生的,所以建议不要加上句点,直接采用content: ‘ ‘;空格即可,修改后的效果clearfix_ie8_2
kohana3.2部署到新浪SAE平台所需要的修改
近日学习用kohana框架,写了一个在线查字的小应用。在本地测试良好,效果图
主要实现的是按部首、按拼音查检索文字,搜索汉子查询。
主要业务逻辑很简单。预览地址请点击这里 现在部署在SAE平台上面。一些问题的参考文档来自这里
正常运行
本地测试完成代码,刚刚部署到SAE平台上时会出现这样的错误。
ErrorException [ Warning ]: Set the ini directive 'unserialize_callback_func' without permission
可以看到kohana完善的错误信息提示已经指向了APPPATH/bootstrap.php中得这一行
ini_set('unserialize_callback_func', 'spl_autoload_call');
这个是因为SAE平台禁用了ini_set()函数的原因,已经没有权限执行了。
解决办法就是直接注释,这个注释的影响是
“代码中使用了unserialize(),并且其解析的结果是一个对象,同时这个对象对应的类还没有定义。这种情况下就会导致一个错误。”来自上面那篇参考文章。
第二个错误则是日志、文件cache不能正常写入了。
Kohana_Exception [ 0 ]: Directory APPPATH/logs must be writable
这个是因为SAE平台禁止了程序对本地的文件进行操作,所以也就没有权限了。“唯一可以直接使用并提供了写入权限的是一个虚拟目录SAE_TMP_PATH。但是这个目录会在php脚本执行完后销毁,所以实际上并不能真正起到缓存的作用。”
解决办法 同样注释掉
Kohana::$log->attach(new Log_File(APPPATH.'logs'));
这样则禁用了日志功能了,不过对于一般的程序来说没有太大的影响。
加入SAE的缓存目录常量
Kohana::init(array( 'base_url' => '/', 'index_file' => 'index.php', 'cache_dir' => SAE_TMP_PATH // 这里 ));
至此如果你的程序不用缓存,那么配置好SAE平台的数据库连接参数等,程序就能正常访问了。
提示一下:
SAE的数据库参数hostname的常量,这个一定要注意,最好把SAE_MYSQL_PORT这个端口常量加上去,否则出现数据库连接不上的问题,但这个问题不容易被注意到,好吧,我就是好不容易才注意到的。SAE云平台的mysql端口不是默认的3306所以我刚开始时没有加上这个端口常量,想不出问题原因,最后登录sae后天,进入管理mysql数据库才看到,原来sae的mysql端口是3307
于是加上了这个端口常量,果然好了。。
'hostname' => SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT, 'database' => SAE_MYSQL_DB, 'username' => SAE_MYSQL_USER, 'password' => SAE_MYSQL_PASS, 'persistent' => FALSE,
因为还有考虑到本地环境运行的问题;所以我再bootstrap.php中加入了SAE常量,值为true或false,true为sae,false为本地
最后bootstrap.ph的代码修改为
// 添加sae的环境控制,也能让程序在本地正常运行
define('SAE', TRUE);
if( ! SAE){
define('SAE_TMP_PATH', APPPATH.'/cache');
}
/**
* 本地环境,非SAE平台的独立设置
* 注意这一段必须在 spl_autoload_register(array('Kohana', 'auto_load')); 之后
* 否则Kohana类未加载情况下,调用$log会出错
*/
if( ! SAE ){
// SAE不支持ini_set函数的运行
ini_set('unserialize_callback_func', 'spl_autoload_call');
// SAE暂不支持对文件夹进行文件写入,暂时关闭日志
Kohana::$log->attach(new Log_File(APPPATH.'logs'));
define('SAE_MYSQL_HOST_M', 'localhost');
define('SAE_MYSQL_PORT', '3306');
define('SAE_MYSQL_DB', 'xhzd');
define('SAE_MYSQL_USER', 'root');
define('SAE_MYSQL_PASS', 'root');
}
使用SAE memcache 缓存
不过我的这个查字程序在部首;拼音列表,以及部首拼音相关的文字这些操作都用了缓存的。所以在sae上文件缓存是用不了了,但是还有memcache缓存啊。
因为SAE平台的memcache缓存启用不是原生的new memcache,而是memcache_init()所以程序还得改下。要改的地方比较简单。大致思路就是重写Kohana_Cache_Memcache的构造函数,重写初始化_memcache
modules\cache\classes\cache\memcache.php
class Cache_Memcache extends Kohana_Cache_Memcache {
public function __construct(array $config) {
parent::__construct($config);
// SAE平台则初始化sae平台memcache
if( SAE ){
$this->_memcache = memcache_init();
}
}
}
不过还是有问题,在SAE平台上会显示 modules\cache\classes\kohana\cache\memcache.php
call undefined function $this->_memcache->addServer() 估计也是被禁掉了。
那也好办注释掉就好了
/**
* 区别sae平台以及本地环境
*/
if( ! SAE){
// Add the memcache servers to the pool
foreach ($servers as $server)
{
// Merge the defined config with defaults
$server += $this->_default_config;
if ( ! $this->_memcache->addServer($server['host'], $server['port'], $server['persistent'], $server['weight'], $server['timeout'], $server['retry_interval'], $server['status'], $server['failure_callback']))
{
throw new Cache_Exception('Memcache could not connect to host \':host\' using port \':port\'', array(':host' => $server['host'], ':port' => $server['port']));
}
}
}
因为kohana默认采用的是文件缓存
所以在调用Cache::instance();前应当Cache::$default = 'memcache';
至此,memcache缓存就能正常的运行了。Kohana框架在SAE平台上的主要修改也完成,不过肯定还有一些不知道的问题,主要是对于SAE平台的不熟悉以及SAE平台处于安全考虑禁用的一些函数、方法等。
最后宣传下个人在sae上的这个应用地址欢迎访问http://xhzd.sinaapp.com/
centos6安装包过程中出现的问题
今天安装centos6后,准备测试下mysql的主从配置。因为centos6采用的是最小安装方式,所以好到安装包都没有。刚才也不知道是什么原因。
好久没有用了,linux命令又都快忘光了。首先还是网卡设置
更新yum源
其中默认是官方的源,不过我用的一般是163网易的源。
# CentOS-Base.repo # # This file uses a new mirrorlist system developed by Lance Davis for CentOS. # The mirror system uses the connecting IP address of the client and the # update status of each mirror to pick mirrors that are updated to and # geographically close to the client. You should use this for CentOS updates # unless you are manually picking other mirrors. # # If the mirrorlist= does not work for you, as a fall back you can try the # remarked out baseurl= line instead. # # [base] name=CentOS-$releasever - Base baseurl=http://mirrors.163.com/centos/6/os/$basearch/ gpgcheck=1 gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6 #released updates [updates] name=CentOS-$releasever - Updates baseurl=http://mirrors.163.com/centos/6/updates/$basearch/ gpgcheck=1 gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6 #packages used/produced in the build but not released #[addons] #name=CentOS-$releasever - Addons #baseurl=http://mirrors.163.com/centos/$releasever/addons/$basearch/ #gpgcheck=1 #gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6 #additional packages that may be useful [extras] name=CentOS-$releasever - Extras baseurl=http://mirrors.163.com/centos/6/extras/$basearch/ gpgcheck=1 gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6 #additional packages that extend functionality of existing packages [centosplus] name=CentOS-$releasever - Plus baseurl=http://mirrors.163.com/centos/6/centosplus/$basearch/ gpgcheck=1 enabled=0 gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6
因为centos是最小化安装所以很多命令库都没有,要一一安装比如
-bash: wget: command not found 安装 wget
-bash: make: command not found 安装 make
还有编译工具如gcc等。这下就可以直接yum install … 了。
不过总是有这个错误
【/repomd.xml: [Errno 14] PYCURL ERROR 6 - ""】想不到原因,搜索得到一篇文章。centos yum 源 问题解析
其中的解释说了很清楚了“
此时聪明的我马上想到了是不是服务器解析不了域名了,导致repomd.xml下载不下来呢?
然后我就ping了一下mirrors.ustc.edu.cn , 果然出现错误:ping: unknown host mirrors.ustc.edu.cn。显然是DNS配置问题了,DNS域名服务器IP地址配的不对。”
解决办法:1、在其他机器上ping源镜像地址,把/etc/hosts里面 加了一行 mirrors.ustc.edu.cn 202.38.95.110,不过这是权宜之计 。2、推荐使用,需要配置正确的DNS。方法是:打开/etc/resolv.conf 文件,加入一行 nameserver ip。此处把ip换成IDC运营商给的DNS的地址就可以了。我的加上了google的dns地址 nameserver 8.8.8.8
这样yum 就可以正常下载,自动安装了。
然后就继续安装vsftpd,这里就是遇上了,执行make时,遇上command not found的问题;经查make包没有安装,yum直接安装上便好。
其中vsftd安装成功后,遇上553 Could not create file问题。经搜索得知。
可能一、是文件目录中的写入权限不够或者是目录所有者及用户组不对。可能二、/etc/vsftpd.conf 中write_enable属性是否为write_enable = yes
以新添加的username为例。
useradd -d /opt/ftp -g ftp-s /sbin/nologin username
1、其中 /opt/ftp的写入权限没有;chmod 755 /opt/ftp 即可
2、owner应该是username,group应该是ftp组;chown -v username:ftp /opt/ftp
在编译mysql中欧make时,遇到了
【/depcomp: line 571: exec: g++: not found】 这样的问题,查找gcc的已安装包
再查看一下本机上与gcc相关的安装包有哪些,缺少gcc-c++包
yum install gcc-c++ -y
安装之后
再次进入mysql目录,make clean 再重新编译。
不过又碰到问题了。
【../include/my_global.h:1099: 错误:对 C++ 内建类型 ‘bool’ 的重声明】搜索得来的解决方案
“再次make && make install 后出现错误
../include/my_global.h:1099: 错误:对 C++ 内建类型 ‘bool’ 的重声明
这个错误 是不是你 先./congfigure 又 装的GCC 又make 的?
是的话 重新./configure 在make clean make make install 就解决了” 网上好东西就是多,确实如此,真是要多分享啊。
还是mysql编译中,遇见了【xmalloc.h:29:31: 错误:readline/rlstdc.h】这样的问题,不过没有搜索到对应的解决方法。个人觉得刚才多次make && make install 后可能出现安装了,但部分内容没有卸载清除干净的问题,于是执行
[root@localhost mysql-5.0.81]# make uninstall [root@localhost mysql-5.0.81]# make clean [root@localhost mysql-5.0.81]# make && make install
这次执行便成功了,没有问题了。
通过yuicompressor-2.4.7压缩css或js的php应用文件
yuicompressor这是个很好的工具,通过java库编译css或js文件进行压缩。压缩css或者js文件的好处是很多的,减少数据请求量,可以更快的进行数据传输,防止其他人进行窥探或整体直接挪用等等。。。
首先你要去下载一个yuicompressor现在最新版本是2.4.7 下载地址: yuicompressor 使用方法怎么工作在这里都有详细的说明,就不一一介绍了。
最常用的yuicompressor语法就是
java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js --charset utf-8
其中需要注意的地方就是 如果不在yuicompressor-x.y.z.jar这个文件目录下,需要采用绝对的路径比如 E:/compressor/yuicompressor/build/yuicompressor-x.y.z.jar 这样的。同样需压缩文件myfile.js和压缩后输出的文件myfile-min.js 也是一样的采用绝对的路径。
好了,有了yuicompressor后;就要首先有一个java环境,不知道是否已安装java环境的可以通过 运行 ->cmd 输入
java -version
如果看到
java的版本结果就说明java的运行环境是ok的了。如果没有这个结果,不用担心可以去oracle官网去下载。如果觉得下载比较慢可以直接百度搜索java jdk下载,下载完成后下一步,下一步安装完成即可。
不出问题,你现在就可以正常的运行yuicompressor了,能够进行完成压缩文件了。
但是这样就出现了一个问题每次通过这样来执行,只能执行一个文件。我们的css和js文件通常有很多,不能一下完全执行,所以就写了一个小应用,直接输入本地的css和js目录就可以直接遍历压缩完成,这样就很省事了。
三个文件index.php ,index.tpl.html , do.php 很小
好吧,直接上码。
index.php
<?php /** * @author alex * @time 2011年12月1日 * @todo php通过yuicompressor批量压缩css和js文件 * @email leiyu_ai@qq.com */ session_start(); require_once 'index.tpl.html'; ?>
index.tpl.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>compressor js/css</title>
<style type="text/css">
body { font: 12px Microsoft Yahei, Verdana, Geneva, sans-serif, "宋体"; }
h1,h2,h4 { margin: 0; padding: 0; font-weight: normal; }
input { border: 1px solid #eee; }
form span { display: inline-block; width: 80px; }
form h4 { margin-bottom: 10px; }
.go { border-color: #000; }
</style>
</head>
<body>
<?php
$_SESSION['rand'] = mt_rand(100,999);
?>
<form action="do.php" method="post">
<h4><span>css文件目录</span><input type="text" name="cssdir" /></h4>
<h4><span>js文件目录</span><input type="text" name="jsdir" /></h4>
<h4><input type="submit" name="go" value="提交" /><input type="hidden" name="rand" value="<?php echo $_SESSION['rand'];?>" /></h4>
</form>
</body>
</html>
do.php
<?php
/*
* 示例:我的yuicompressor-2.4.7.jar是放在这个地址下的,所以在运行前请更改为你的存放地址
* $cmd = "java -jar E:/compressor/yuicompressor-2.4.7/build/yuicompressor-2.4.7.jar --type js --charset utf-8 -o E:/tmp/js/home.min.js".
* " E:/tmp/js/home.js";
*/
session_start();
header('Content-type:text/html; charset=utf-8');
$rand = $_POST['rand'];
$srand = isset($_SESSION['rand'])? $_SESSION['rand']: '';
$submit = $_POST['go'];
if ($rand == $srand ){
if ($submit){
$jsdir = $_POST['jsdir'];
$cssdir = $_POST['cssdir'];
if ( !empty($jsdir) || !empty($cssdir)){
// 获取所有的文件集合
$jslist = getFileList($jsdir);
$csslist = getFileList($cssdir);
// 压缩js、css文件内容
$bool = doIt($jslist);
$boolc = doIt($csslist);
if ( $bool || $boolc){
echo $jsdir.'|'.$cssdir.' 目录执行成功';
}else{
echo $jsdir.'|'.$cssdir.' 目录执行失败';
}
}else {
echo '请输入css或js的文件目录';
}
echo ' <a href="'.$_SERVER['HTTP_REFERER'].'">返回首页</a>';
}
unset($_SESSION['rand']);
}
function getExt($file){
return strrev(substr(strrev($file), 0, strpos(strrev($file),'.')));
}
function getName ($file){
return strrev(substr(strrev($file), strpos(strrev($file),'.')+1 ));
}
function getPathFile($dir, $file){
return $dir.DIRECTORY_SEPARATOR.$file;
}
function doIt($list){
$tfile = $list[0][0];
$ext = getExt($tfile);
foreach($list as $key=>$val){
$cmd = "java -jar E:/compressor/yuicompressor-2.4.7/build/yuicompressor-2.4.7.jar --type {$ext} --charset utf-8 -o {$val[1]}".
" {$val[0]}";
exec($cmd, $output, $rv);
// 执行成功
if ( $rv == 0){
// 删除源文件
unlink($val[0]);
// 重命名新的压缩文件
rename($val[1], $val[0]);
}else {
$str .= $val[0].',';
}
}
if (!empty( $str)){
echo $str.' 执行失败';
return false;
}else {
return true;
}
}
function getFileList($dir){
$filelist = array();
if (is_dir($dir)){
$handle = opendir($dir);
while(($file = readdir($handle)) !== false){
if ( $file == '.' || $file == '..') continue;
$tmpdir = getPathFile($dir, $file);
if ( is_dir( $tmpdir)){
$rs = getFileList( $tmpdir);
if ( !empty($rs)){
$filelist = array_merge($filelist, $rs);
}
}else {
$filename = getName($file);
$ext = getExt($file);
$file = getPathFile($dir, $file); // 源文件完整路径
$minname = getPathFile($dir, $filename.'.min.'.$ext); // 压缩目标文件名称完整路径
$filelist[] = array($file, $minname);
}
}
closedir($handle);
return $filelist;
}else{
return false;
}
}
?>
ok完成。现在展示下我的测试结果
css文件
压缩前: 压缩后:
js 文件
压缩前: 压缩后:
效果还是很明显的~~ ^_^
useless setInterval call (missing quotes around argument?) setInterval 参数错误
在写javascript过程中使用到setInterval时,需要传递一个类似于 main.check()这样的参数时,出现了这样的错误信息。
Firefox错误信息:useless setInterval call (missing quotes around argument?)
ie错误信息: 参数无效,42行。
<script language="javascript">
jQuery.noConflict();
jQuery(function($){
$(document).now();
});
jQuery.fn.extend({
now: function(){
var main = this;
this.extend({
gettime: function(){
var date = new Date();
jQuery('body').html(date.getTime());
}
});
// setInterval( main.gettime(), 1000); // 错误产生地方
setInterval( function(){ main.gettime() }, 1000); // 修改为这样既可
}
});
</script>
解决方法很简单。在网上搜索到的。在很多时候比如setTimeout等这样的参数或者自定义的回调函数调用时,都有可能会遇到这样的问题,
主要是因为“main.method()”这样的格式方法所导致的,无法作为一整个函数体来执行,所以在外嵌套一个function(){ } 匿名函数体,这样就可以正常执行了。
原文地址是:useless setInterval call (missing quotes around argument?)
有关html Object标签播放flash的AllowScriptAccess与allowNetworking 属性 [转]
原文:AllowScriptAccess 与allowNetworking
最近在测试网站api视频播放时,播放器swf上可以支持全屏但是点击却没有效果。还有在视频播放完毕后,播放器直接无反应,没有推荐内容或重播按钮。只好搜索下,找寻结果。
1,AllowScriptAccess
参数:
sameDomain:仅当 SWF 文件和网页位于同一域中时才允许执行外出脚本访问。这是 AVM2 内容的默认值。
never:外出脚本访问将始终失败。
always:外出脚本访问将始终成功。
AllowScriptAccess 参数可以防止从一个域中承载的 SWF 文件访问来自另一个域的 HTML 页面中的脚本。
对从另一个域承载的所有 SWF 文件使用 AllowScriptAccess=”never” 可以确保位于 HTML 页面中的脚本的安全性。
2,allowNetworking
参数:
“all”(默认值)― SWF 文件中允许使用所有网络 API。
“internal”― SWF 文件可能不调用浏览器导航或浏览器交互 API,但是它会调用任何其它网络 API。
“none”― SWF 文件可能不调用浏览器导航或浏览器交互 API,并且它无法使用任何 SWF 到 SWF 通信 API。
可以控制 SWF 文件对网络功能的访问。调用被禁止的 API 会引发 SecurityError 异常。
当 allowNetworking 设置为 “internal” 时,以下 API 被禁止:
navigateToURL()
fscommand()
ExternalInterface.call()
当 allowNetworking 设置为 “none” 时,除了上面列出的那些 API 外,还会禁止以下 API:
sendToURL()
FileReference.download()
FileReference.upload()
Loader.load()
LocalConnection.connect()
LocalConnection.send()
NetConnection.connect()
NetStream.play()
Security.loadPolicyFile()
SharedObject.getLocal()
SharedObject.getRemote()
Socket.connect()
3,allowFullScreen
参数:
启用全屏模式设置为”true”,否则设置为”false”(默认值)
仅当在响应鼠标事件或键盘事件时才会调用启动全屏模式的 ActionScript。如果在其它情况中调用,Flash Player 会引发异常。
在全屏模式下,用户无法在文本输入字段中输入文本。所有键盘输入和键盘相关的 ActionScript 在全屏模式下均会被禁用,但将应用程序返回标准模式的键盘快捷键(例如按 Esc)除外。
当内容进入全屏模式时,程序会显示一条消息,指导用户如何退出和返回标准模式。该消息将显示几秒钟,然后淡出。
如果某个调用方与 Stage 所有者(主 SWF 文件)没有位于同一安全沙箱,则调用 Stage 对象的 displayState 属性会引发异常。
管理员可以通过在 mms.cfg 文件中设置 FullScreenDisable = 1 对浏览器中运行的 SWF 文件禁用全屏模式。
在浏览器中,必须在 HTML 页面中包含 SWF 文件,才能进入全屏模式。
在独立的播放器或放映文件中始终允许全屏模式。
实例代码:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="100%" height="100%"> <param name="movie" value="falsh.swf" /> <param name="quality" value="high" /> <param name="AllowScriptAccess" value="sameDomain" /> <param name="allowNetworking" value="all" /> <param name="allowFullScreen" value="true" /> <embed src="falsh.swf" width="100%" height="100%" quality="high" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" allowscriptaccess="sameDomain" allownetworking="all" allowfullscreen="true"></embed> </object>
这么大一串代码记住不容易,可以直接使用dreamweaver新建页面,插入swf 然后自动生成这样的代码,还有ie与非ie的不同参数设置代码。不过常用的就是这么几个了
<param name=”allowFullScreen” value=”true” /> <!– 全屏 –>
<param name=”allowNetworking” value=”internal” /> <!– 调用swf内部api–>
<param name=”wmode” value=”opaque” /> <!– 是否透明 –>
<param name=”PLAY” value=”false” /> <!– 是否自动播放,默认为是 –>
<param name=”LOOP” value=”false” /> <!– 是否循环播放,默认为是 –>
强大的jquery弹出层插件blockUI
之前工作中每次需要用到弹出层时,就满地的找。上次也不例外,也这样了。
不过这次发现了一个好东西,jquery的弹出层插件blockUI。
原文介绍地址:强大的jQuery弹出层插件–BlockUI
blockUI官网:http://jquery.malsup.com/block
blockUI GitHub :
先导入jQuery的库文件(小提示:使用Google服务器的压缩版jQuery库文件加载速度会更快),然后再导入BlockUI的库文件
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="images/jquery.blockUI.js" type="text/javascript"></script>
导入库文件后,就可以调用BlockUI了,BlockUI的调用挺简单的,看下面这段代码
$(function(){
$(‘#box_btn’).click(function(){ //给box_btn绑定一个鼠标点击的事件
$.blockUI({ //当点击事件发生时调用弹出层
message: $(‘#box’), //要弹出的元素box
css: { //弹出元素的CSS属性
top: ’50%’,
left: ’50%’,
textAlign: ‘left’,
marginLeft: ‘-320px’,
marginTop: ‘-145px’,
width: ’600px’,
background: ‘none’
}
});
$(‘.blockOverlay’).attr(‘title’,'单击关闭’).click($.unblockUI); //遮罩层属性的设置以及当鼠标单击遮罩层可以关闭弹出层
$(‘.close’).click($.unblockUI); //也可以自定义一个关闭按钮来关闭弹出层
});
});
看了上面的代码,其实你会发觉BlockUI的使用很简单,有2个重要的方法分别是调用弹出层($.blockUI)和关闭弹出层($.unblockUI)。
$.blockUI定义了一个message属性的,该属性的值就定义了要弹出的元素,比如要弹出一个id为box的div元素,就可以这样写:message: $(‘#box’),对应了上面的第4行代码。需要注意的是,要弹出的那个元素在弹出之前要将其在页面中隐藏即设置该元素的CSS样式为display:none。
$.blockUI还定义了一个css属性,该属性可以对弹出层的样式进行再定义。细心的同志可能会打开BlockUI的库文件查看,其实在库文件中也默认定义了一个弹出层的样式,如果你在页面中定义的样式效果并不是很理想,最好是看看库文件中的$.blockUI.defaults的CSS属性。
如果你想了解一些BlockUI的更高级的用法你可以去该插件的官网看看说明文档。
BlockUI的下载地址是:hhttp://jquery.malsup.com/block/#download
2011年末总结系列之个人情感篇
好了,2011年总结系列的最后一部大片终于要上映了,这篇相对于前几篇比较简单,但是个人还是感觉很有难度,因为这个的主题是恋爱。
谈恋爱,首先要有一个对象,而且还必须是女对象,这个是前提。但,悲催的是我没有这个对象,虽然我很想为了这个将来的这个对象亲亲爱爱,为了她加油努力,为了她言听计从,为了她改掉不好的习惯……但是这一切目前也只能是我的空想,就如同js对象的属性,它必须存在于对象之上才能可能被使用,不然就总是会报"未找到该属性"的错误内容。我的那个她还没有出现,所以这一切的一切也只能存在于我的脑海中了。
在之前的生活篇里面也提到了,2012年龙年,第二个本命年里,我最大的期望与理想就是找到一位适合的、相爱的、谈婚论嫁的女朋友!这一目标在2012年里要坚定不移的执行实施!立字为证,明年这个时候,写文汇报。
千里姻缘一线牵,百年修得同船渡。让我遇见你吧。
祝各位朋友新春快乐,龙年吉祥!!!新春快樂!龍年大吉!!!
2011年末总结系列之个人的生活篇
快过年了,几篇总结拖拖拉拉,都快忘记了,当初想写的一些东西了。个人性格有关,就是喜欢拖拖拉拉。。
但还是要写啊。不能说了不写,君子耻其言而过其行,最近某麦说韩寒是人造的,呵呵长篇大论啊。某天要是也有人说我的文章是背后团队策划(别飘起来了啊,说的就你),那就不好了。
要说2011年的个人生活,虽不是很糟糕,但也没什么太多的惊喜,差强人意。。工作上的进步也没有太多,更多的是往专业化的方向更靠近了一点,比起10年还是要好的。下班后的生活也没有太多的改变,上班,下班,余外活动不多。公司里面组织活动,吃吃饭,ktv里面吼两嗓子,不过不多;自己就是看看电影,然后去下博物馆,熏陶熏陶。除这之外的很多时候,找不到理由出去,你出去干啥呢?
几个要好的朋友都不在武汉,所以武汉的朋友圈子几乎没有,只有同事圈子,同事与同学与朋友;怎么说能完全不在一个重量级别上。只要是工作了的人都应该明白和知道的,这就是为什么只有生意场,职场的称呼,没有说朋友场的。朋友在一起,不会因为你的代码写的不好看,或者这个业务逻辑你没有理解做不出来等等顾虑。还有就是职场能交心的人不多,当然也有的,少。在我看了公司就是大家为了一个共同的目的——赚钱而走到一起的,其他的所谓文化,技术,能力等等内容都是虚无飘渺的,不过也不排除职场朋友的存在,虽然都是为了RMB到一起的,但还是有缘分,能够为了共同的RMB而组建为一个团队,为能做一些事情而感到高兴。当然朋友圈子里面也并不是什么问题都没有的,就像宝莱坞电影三傻里面的一句台词“朋友失败,你很伤心;朋友成功,你更伤心”呵呵,事实就是如此,我的朋友们,都是大学时的同学,大家在一起喝过酒,吃过肉,一起玩过游戏,一起出找工作。现在都各地各自忙着,不过还好,都过得不算太坏,吃饭不成问题,但是现今这个社会,只管吃饭还不行。朋友之间也有上有下,有的管理的10多人的团队,有的在辛苦的跑销售,有的在做程序,我呢,一个人苦逼的写一些破代码,直到今天,到公司快一年了,老板还不记得我的名字,我的能量究竟有多小,您始终不记得我的名字,哎,fk。也是与个人原因有关的,这样的我,不善言辞,不善社交,技术不出众,总是做些细碎的工作。我记得和老板说的最多的话,居然是他当初面试我时的交流。额。确实很操蛋。
这一年里,个人的技术风格以及定位有一个初步的认识,但并没有完全做好打算去怎样怎样,这也是自己不自信的原因。没错,你是做了很多事,但是这些事情都是他人可以直接替代的,你的特长时什么?你的风格是什么?你未来的道路是什么?现在我还不能完全答复。这也是要在2012年里面更加的清晰和明了的。很多事情充满了变数,又有很多事情难以改变的。比如你的性格,我的强迫症。
我不知道什么时候起,有了一个动作强迫症,额,这个是我自己命名的,不知道是否真的有这个名词。反正不知道怎么地,就是这样了,比如关门的时候,明明已经锁好了,但是还是得打开,再次的锁一遍,如此反复几次;还有就是上下车的时候,能够很轻松的下车时,总是要摸一下那个车门的扶手;比如关灯时,总是关掉一次,在打开,再关掉,如此如此。比如…还有很多时候老是这个样子,我知道这样不好,想改,可是没几天就又这样了。。真是麻烦,有时候嘴里还念念有词的反复几遍。所以在2012年里,我就想彻底的改掉这毛病。fk强迫症!
24了,老大不小了。朋友们都已经经历或正在经历着恋爱,只有我这棍子,还是这样一直一个这样矗立着。现在父母也开始催了,催你找女朋友,现在只是暂时的催你找女朋友,但是过两年呢?那就是催你结婚了,结婚!女朋友的都没有,去哪结怎么结,我又不搞基。现在就觉着烦了,如果还迟点,那就不是烦人的问题了。没办法文化传统是这样。成家立业,成家立业。所以2012年里,最大的目标和最大的收获就是希望能找到一个女朋友,甚至更好的发展为开始谈婚论嫁(明年双春啊!好年头!加油!!)
好像没什么内容了额,好吧那就先到这里吧。呵呵,对了祝各位新春快乐!龙年大吉!!!
