配置PHP.ini
更改配置项(必须)auto_prepend_file = "C:\xampp\htdocs\auto_prepend_file.php"
更改配置项(可选)allow_url_include = On
auto_prepend_file.php文件内容
<?php
/**
* 引入static文件
* @param {array|string} 相对路径
* @param {string} 当前执行脚本所在的路径__FILE__
*
*/
function import_static($files, $path=NULL){
// 更改当前脚本的执行路径
$old_dir = getcwd();
$tmp_dir = (isset($path)) ? dirname($path): dirname(__FILE__);
chdir($tmp_dir);
// 整理包含文件
if (!is_array($files)) {
$tmp = array();
$tmp[] = $files;
$files = $tmp;
}
// 发送头信息
if (isset($files[0])) {
if (stripos($files[0], '.js') !== false) {
$header_str = 'Content-Type: text/javascript';
} elseif (stripos($files[0], '.css') !== false) {
$header_str = 'Content-Type: text/css';
}
if (!ob_get_contents()) {
header($header_str);
}
}
// 引入包含文件
foreach($files as $key=>$value) {
require_once($value);
}
// 改回当前脚本的执行路径
chdir($old_dir);
}
?>
使用方法
"a.js"、"b.js"和"../c.js"是待合并的JS文件,将其合并为base.js.php,则base.js.php中的代码如下:
<?php
import_static(array(
'a.js',
'b.js',
'../c.js',
'../moduleB/all.js.php' // 也可引用.php文件
), __FILE__);
?>
在HTML页面中使用<script type="text/javascript" src="base.js.php"></script>即可引入。
产品上线前,使用批处理文件进行处理,主要做两方面的工作
- 将"*.js.php"输出到"*.js"文件,并删除"*.js.php"。命令行:php *.js.php > *.js
- 将HTML页面中对"*.js.php"的引用替换为"*.js"。preg_replace()
PS:import_static函数解决了PHP中include()处理相对路径的问题。
待续。。。
| 寤寐思服 | |
| 往事越千年 |
引自“往事越千年,魏武挥鞭,东临碣石有遗篇。”意思是以前的事已经过去了千百年了(越是过去、逝去的意思),魏武帝曹操曾带领军队出征,登上碣石山且创作了观沧海一诗。 有些世事变迁,沧海桑田的意思。 |
| 私权不立无以公民 | |
| 貌不惊人 |
解 释:指相貌平常,没有什么引人注意的地方。 一般用来引出令人吃惊或出乎意料的下文。常用在转折句中。 出 处:清·钱彩《说岳全传》第11回:“看你这般人不出众,貌不惊人,有何本事,要想做状元么?” 貌不惊人,言不压众。 |
1、display:inline-block
让一个元素具有“区块元素”的属性(可以设置width和height),又具有“内联元素”的属性(不产生换行)。
2、IE中的inline-block
IE6不支持这个属性,但IE8开始支持这个属性。
让IE6内联元素具备inline-block特性
由于inline-block会触发IE的layout,所以IE6中只要设置{display:inline-block;}即可。
让IE6区块元素具备inline-block属性,有两种方法
A、可以先触发layout,再设置为inline,需要注意的是这两个display必须在两个CSS声明中才有效,代码如下:
div {
width:400px;
height:200px;
display:inline-block;
}
div {
display:inline;
}
B、直接设置为inline,再利用zoom来触发layout来实现类似效果:
div {
width:400px;
height:200px;
*display:inline;
*zoom:1;
}
3、其它浏览器
其它浏览器都支持这个属性,但Firefox从3.0才开始支持这个属性,对于之前的版本可以利用其私有属性{display:-moz-inline-box}来实现类似效果,但也可以忽略3.0之前的版本(这些版本的浏览器很少有人使用了)。
4、参考文献
1、include和require区别
当要包含的文件不存在时,include产生一个警告(Warning),该语句后面的程序会继续执行;而 require则导致一个致命错误(Fatal error),程序就此终止。
2、路径问题(适用于include和require)
+c.php
+folder1
+----a.php
+----folder2
+--------b.php
a.php
include 'folder2/b.php';
b.php
include 'c.php';
执行a.php过程
- 包含"b.php",并执行"b.php"
- 在folder1(当前工作目录,"a.php"所在目录下)下查找"c.php",查找不到则执行下一步
- 在folder2(当前文件目录,"b.php"所在目录下)下查找"c.php"。
无论是"a.php",还是"b.php",若include路径中含有"../",则都在当前工作目录(folder1,"a.php"所在目录)的上级目录中查找
3、变量作用域
- 一个文件被包含时,所包含的代码继承了“include”所在行的变量范围,该行处可用的任何变量在被包含的文件中都可用。主要针对于函数中的include。
- 所有在包含文件中定义的函数和类都具有全局作用域,和变量不同。普通变量的变量作用于继承了“include”所在行的变量范围,例如函数中的include。
4、include_path
set_include_path(
get_include_path()
. PATH_SEPARATOR . './library'
. PATH_SEPARATOR . './application/models'
);
默认的include_path=".;C:\xampp\php\PEAR",使用set_include_path设置后,(不论文件的包含层级怎样)后续的所有程序都会使用该值,该函数可多次调用。
1、基础知识
HTTP流的概念
持久HTTP流只是一种是HTTP链接保持打开状态的简单方法,这样大量的HTTP请求不需要进行打开和关闭操作就可以被一个一个地发送。
常用PHP函数
sleep(10); //暂停 10 秒 ob_flush(); flush();
PHP向浏览器周期性发送数据的功能,并不是所有服务器都可行,更多相关信息请参阅www.php.net/flush。关于flush的内容,请参考深入理解ob_flush和flush的区别。
<script>标签的执行时间
在绝大多数浏览器中,当还没有读取到</script>结束标签时,代码是不会执行的。
配置脚本最大执行时间
在Comet执行时,经常超过了php脚本的最大执行时间,因此需要配置maxexecutiontime(详细参考:PHP - PHP.ini配置中文解释),并结合心跳机制。
var iTimer;
function heartbeat() {
clearTimeout(iTimer);
iTimer = setTimeout(function(){
// 执行一次Comet
// 300为服务器端配置的max_execution_time
}, 300);
}
2、Comet的实现方法
IE浏览器
demo.html
<script type="text/javascript">
var oPage = new ActiveXObject("htmlfile");
oPage.open();
oPage.write("<html><body></body></html>");
oPage.close();
oPage.body.innerHTML = '<iframe src="connection.php"></iframe>';
oPage.parentWindow._parent = self;
function heartbeat() {}
function modifiedAt() {}
</script>
- oPage.parentWindow访问的是HTMLFile对象的window属性
- connection.php中JS使用top或parent访问的不是demo.html的window属性
- connection.php中JS使用top或parent访问HTMLFile对象的window属性
connection.php
<html>
<head></head>
<body>
<script type="text/javascript">
parent._parent.heartbeat();
parent._parent.modifiedAt();
</script>
</body>
</html>
其他浏览器
demo.html
var oXHR = new XMLHttpRequest();
oXHR.open('get', 'connection.php', true);
oXHR.readystatechange = function() {
switch (oXHR.readyState) {
case 3:
alert(oXHR.responseText);
break;
case 4:
alert('done');
}
};
- 每次从服务器收到数据时(即服务器端调用“ob_flush(); flush();”时),都会触发readyStatechange事件。
- readyState等于3时,oXHR.responseText返回的内容,不是本次变化新增的内容,而是之前接受到的内容+本次变化新增的内容。
3、LiveConnect的HTTP流
LiveConnect是Firefox、Safari和Opera支持的一种未充分利用的技术,通过它可以再JavaScript种使用Java对象,但客户机必须安装JRE,并且浏览器必须启用Java。
4、服务器端发送的Dom事件
示例
demo.html
<body>
<event-source id="iBox" src="connection.php" />
<script type="text/javascript">
var iBox = document.getElementById('iBox');
iBox.addEventListener('modified', function(oEvent){
console.log(oEvent);
});
</script>
</body>
connection.php
<?php
header("Content-type:application/x-dom-event-stream");
while (true) {
echo 'Event: modified';
echo 'data: 5:23:06';
ob_flush();
flush();
sleep(1);
}
?>
使用的就是一个保持打开的链接 - Event后面是事件名称,其余的是event对象的属性;每两个事件之间使用一个空白换行区分。
- Target后面紧跟触发的元素,格式类似于CSS选择器。 * 疑问之处,服务器端事件处理函数会不会触发浏览器的默认事件,即想<input type="submit"/>发送click事件,会不会提交表单,还是仅调用该元素的click绑定函数?
- 服务器端发送的Dom事件可以触发自定义事件,上例中的”modified”事件就是自定义事件。还可以触发客户端的UI事件,Dom Level 3事件规范中命名的所有事件都能够通过服务器端的Dom事件来触发。
- 不一定要为
元素绑定事件处理函数,每个事件都将自动传给目标元素,并由钙元素的事件处理函数负责处理,如下例。
返回内容
Event: click Target: #iBox button: 2 screenX: 0 screenY: 0 Event: click Target: Document data: See you later!
支持性
到2006年10月为止,Opera9.0.1是唯一支持服务器端发送的Dom事件的浏览器,经测试Opera 11.52不支持。
5、连接管理
HTTP1.1协议中规定,一个客户端最多允许同时保持两个连接(这点取决于浏览器,迅雷等下载工具也会提高这个并发的数目)。使用Comet的后果就是会占用一个连接,具体的解决办法是为Comet指定专门的子域名。
Comet也会增加服务器的并发数目,所以在使用Comet技术之前要与维护服务器的人员交流,确保他们理解所要实现的功能,并给与支持。
Comet技术早在2007年左右就有人提出,最早的一篇文章是What else is burried down in the depth’s of Google’s amazing JavaScript?,至今仍未大面积使用。主要原因还在于它对服务器的开销和开发模式上的改变,另一方面使用Ajax绝大多数情况下可以很好的替代Comet。