曾经写过一个javascript自动常见form,并提交到自动创建的iframe的一个应用。由于提交之后跳转到另外一个页面,然后回退,会返现form的提交请求又自动重发了一次,因为是提交到一个隐形的iframe中的,我就在提交之后把iframe给删除了,但是回退后还会重新发送提交请求,我没有办法,知道有一天我在走路的时候,突然想到问题可能出现在为删除的form上,于是,我测试了一个,提交form之后就删除form,然后回退就没有该问题了,困扰了我几个月的问题终于真相大白、水落石出了。
关于浏览器的访问限制
1. 跨域访问是浏览器非常明显的访问限制
2. 另外除了根据域名的访问限制外,还有协议间的限制,如:http 和 https即使是同域也不能相互访问;
我原来以为跨域限制应该不限制http和https之间的访问,知道做的时候才发现是有这方面的限制的。做浏览器这方面开发是需要更多地了解浏览器的特性的。
PHP 中的内存限制
今天在做图片上传部分的工作,上传后的图片需要做处理,a机器上总报PHP内存耗尽的错误,检查了一下php.ini里面memory_limit 设置为16M,应该够用了吧,才处理2M的图片;后来检查了一下处理图片需要很大内存的,如果图片尺寸很大的话,即使图片占用空间不大,处理起来也很费内存的;2M的图片需要50多M的内存。
但是奇怪的是,在b机器上处理图片就没有问题,而b机器上php.ini 的设置为:
memory_limit = 8M ;
这就奇怪了,然后使用 php -r "echo ini_get(‘memory_limit’);" , 在 a机器上显示结果为: 16M ,在b机器上没有显示;
于是,怀疑b机器上的memory_limit没有生效;问了一下百度,才知道要是memory_limit生效,则PHP在编译的时候需要 –enable-memory-limit ; 于是查了一下a机器和b机器上的编译选项,都没有明确指定 –enable-memory-limit ;
在用php -v 查看一下,
a机器版本php 5.2.5
b机器版本php 5.1.5
大概是默认的编译选项不同吧! 看了一下PHP 5.2.5 的NEWS ,果然PHP 5.2.5默认是开启的,而PHP 5.1.5 默认是不开启的。
启发:
我们在给PHP添加内存限制是只是在php.ini中添加了 memory_limit 的设置,却没有验证是否达到了效果;
这就教育我们做事要“善始善终”, 不能只是做完了就算完了,一定要想办法证明自己做的没有问题,否则事情就没有做完。
mc_watch
本文是一个查看mc的PHP脚本文件,用法简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
<?php /** * @brief: this is a qiangda de tools of watching memcache. * @author: phpor <lijunjie1982@yahoo.com.cn> * @date: 2010-07-26 16:00:00 * @version: 1.1 */ $arropt = getopt('h:p:i:n:rw:e:E:'); if(!isset($arropt['h']) || !isset($arropt['h'])) showHelp(); $host = $arropt['h']; $port = $arropt['p']; $interval = isset($arropt['i'])?$arropt['i']:1; $count = isset($arropt['n'])?$arropt['n']:0; $relative = isset($arropt['r']); $width = isset($arropt['w'])?$arropt['w']:15; $arrExtra = array(); if (isset($arropt['e'])) { $arrE = explode(':',$arropt['e']); foreach ($arrE as $field) { $arrExtra[$field] = $field; } } $mc = new Memcache(); if(!@$mc->connect($host,$port)) { die("connect $host:$port error\n"); } init(); $arrShow = array_merge($arrShow, $arrExtra); if (isset($arropt['E'])) { $arrE = explode(':',$arropt['E']); foreach ($arrE as $field) { unset($arrShow[$field]); } } $arrStats = $mc->getStats(); showHead($arrStats); show($arrStats,$relative); $i = 1; while($count ==0 || $i++ < $count) { sleep($interval); $arrStats = $mc->getStats(); show($arrStats,$relative); } exit(0); function showHelp(){ echo <<<eof Usage: -h host : -p port : -i interval : -n counts : -w field width: default 15 -e extends fields: eg: "bytes_read:bytes_written" -E erase fields: eg: "cmd_get:cmd_set" -r : show relative eg : 1. php mc_watch.php -h 10.65.129.61 -p 11241 -i 1 -n 10 -r 2. php mc_watch.php -h 10.65.129.61 -p 11241 -i 1 -n 10 -r -e "bytes_read:bytes_written" -E "cmd_get:cmd_set" eof; exit(0); } function init() { global $arrShow, $arrOld; $arrShow = array( 'curr_connections' =>'curr_conn', 'cmd_get' =>'cmd_get', 'cmd_set' =>'cmd_set', 'get_hits' =>'get_hits', 'get_misses' =>'get_misses', 'hits_rate' =>'hits_rate', 'evictions' =>'evictions' ); $arrOld = array(); foreach ($arrShow as $key=>$val) { $arrOld[$key] = 0; } } function showHead($arrStats) { global $arrShow, $width; echo "pid: ".$arrStats['pid'] ."\tserver_time: ".date('Y-m-d H:i:s',$arrStats['time']) ."\tmemcache_version: ".$arrStats['version'] ."\tmem_used: ".(getUse() / 1024 / 1024)."MB" ."\n"; foreach($arrShow as $val) { printf("%{$width}s",$val); } echo "\n"; } function show($arrStats,$relative = false) { global $arrShow,$arrOld, $width; $cnt_hits = $relative?$arrStats["get_hits"]-$arrOld["get_hits"]:$arrStats["get_hits"]; $cnt_get = $relative?$arrStats["cmd_get"]-$arrOld["cmd_get"]:$arrStats["cmd_get"]; foreach($arrShow as $key=>$title) { if ($key == "hits_rate") { printf("%{$width}s",sprintf("%0.2d%s", ($cnt_hits/$cnt_get)*100, "%")); } if(!isset($arrStats[$key])) continue; $val = $arrStats[$key]; printf("%{$width}s",$relative?$val - $arrOld[$key]:$val ); } echo "\n"; $arrOld = $arrStats; } function getUse() { global $mc; $arr = $mc->getStats('slabs'); return $arr['total_malloced']; } |
javascript 中的类属性与实例属性
下面的代码实现了javascript中类属性与实例属性:
function myObject() {
var instance_data = 100;
this.getInstanceData = function() {
return instance_data;
}
this.setInstanceData = function(v) {
instance_data = v;
}
}
// 使用一个匿名函数去修改构造器的原型 myObject.prototype, 以访问该匿名函数中的upvalue
void function() {
var class_data = 10;
this.getClassData = function() {
return class_data;
}
this.setClassData = function(v) {
class_data = v;
}
}.call(myObject.prototype);
// 创建对象
//
var obj1 = new myObject();
var obj2 = new myObject();
obj1.setInstanceData(10);
alert(obj2.getInstanceData()); // 输出100
obj1.setClassData(200);
alert(obj2.getClassData()); // 输出200 、
Javascript 中构造单实例
下面几段代码,比较耐人寻味,里面体现了一些javascript的运行本质的东西,需要慢慢理解:
function aFunc() {
function myfunc() {
//...
}
return myfunc;
}
var f1 = aFunc();
var f2 = aFunc();
alert(f1 === f2); //false
function aFunc2() {
var myfunc = function() {
//...
}
return myfunc;
}
var f1 = aFunc2();
var f2 = aFunc2();
alert(f1 === f2); // false
function aFunc3() {
function myfunc() {
//...
}
return function () {
return myfunc;
}
}
var f1 = aFunc3();
var f2 = aFunc3();
alert(f1 === f2); // false
var aFunc4 = function () {
function myfunc() {
//...
}
return function () {
return myfunc;
}
}();
var f1 = aFunc4();
var f2 = aFunc4();
alert(f1 === f2); // true
时间
Firefox 配置参数详解
Firefox 配置参数详解
参考链接:
http://blog.techippo.org/archives/211
http://preferential.mozdev.org/preferences.html
一个不错的debug函数
摘自:PHP手册
通过debug_backtrace()函数可以找到
<?php
// useful and comfortable debug function
// it's show memory usage and time flow between calls, so we can quickly find a block of code that need optimisation...
// example result:
/*
debug example.php> initialize
debug example.php> code-lines: 39-41 time: 2.0002 mem: 19 KB
debug example.php> code-lines: 41-44 time: 0.0000 mem: 19 KB
debug example.php> code-lines: 44-51 time: 0.6343 mem: 9117 KB
debug example.php> code-lines: 51-53 time: 0.1003 mem: 9117 KB
debug example.php> code-lines: 53-55 time: 0.0595 mem: 49 KB
*/
function debug()
{
static $start_time = NULL;
static $start_code_line = 0;
$call_info = array_shift( debug_backtrace() );
$code_line = $call_info['line'];
$file = array_pop( explode('/', $call_info['file']));
if( $start_time === NULL )
{
print "debug ".$file."> initializen";
$start_time = time() + microtime();
$start_code_line = $code_line;
return 0;
}
printf("debug %s> code-lines: %d-%d time: %.4f mem: %d KBn", $file, $start_code_line, $code_line, (time() + microtime() - $start_time), ceil( memory_get_usage()/1024));
$start_time = time() + microtime();
$start_code_line = $code_line;
}
////////////////////////////////////////////////
// example:
debug();
sleep(2);
debug();
// soft-code...
$a = 3 + 5;
debug();
// hard-code
for( $i=0; $i<100000; $i++)
{
$dummy['alamakota'.$i] = 'alamakota'.$i;
}
debug();
usleep(100000);
debug();
unset($dummy);
debug();
?>
基于事件机制的PHP程序设计
PHP为什么没有内置事件机制?
1. PHP本身是一种脚本语言,他是因web诞生的,这么多年的发展,也是为web而发展的
2. 通过事件可以实现一种设计模式(中介者模式),但是似乎PHP不太讲究模式
下面是从其他语言中借鉴过来的思想,心血来潮才仓促之间写下了下面这些 代码,希望能对各位读者,也对自己能够有些启发:
<?php
/**
* @brief: 基于事件机制的PHP程序设计
* @author: phpor <lijunjie1982@yahoo.com.cn>
* @date: 2009-10-10 14:00:00
* @version: 1.2
*/
// 修改历史:
// version 1.1:
// 1. 使用了call_user_func_array函数,大大简化了事件处理,简化了Event类
// 2. 给支持事件的类定义事件参数类
// version 1.2:
// 1. 添加了事件的默认处理器,否则不绑定事件时会报错
/**
* @brief: 事件基类,提供事件相关的一些方法
*/
class Event {
protected $_arrEvent = array();
protected function defaultEventHandler($sender = null, $misc = null) {
return true;
}
public function addEventHandler($eventName, $handler) {
if (!isset($this->_arrEvent[$eventName]) || !is_callable($handler)) {
// 弱类型语言,这里就不报错了
return false;
}
$this->_arrEvent[$eventName] = $handler;
return true;
}
protected function triggerEvent($eventName,$args) {
if(isset($this->_arrEvent[$eventName]) ) {
return call_user_func_array($this->_arrEvent[$eventName], array($this,$args)); // 触发事件时,一般第一个参数为sender
}
return true;
}
}
/**
* @brief: 一个实现了事件机制的表单类
*/
class Form extends Event{
public function __construct () {
// 这里初始化自己支持的事件
$this->_arrEvent = array ("onsubmit"=>array($this,"defaultEventHandler")); // 注意这里不能初始化为null,null就等于没有isset
}
public function submit($action) {
// 在执行动作前触发事件
if (!$this->triggerEvent("onsubmit",new FormEventArgs(array("action"=>$action)))) return false;
echo "submitedn";
// 其实对于有些操作,在执行动作后也可以触发某个事件
return true;
}
}
/**
* @brief: 一个类如果要支持事件,最好定义一个事件参数类,便于传递自己需要抛出的信息
*/
class FormEventArgs {
private $_arrData = array();
public function __construct($arrData = array()) {
$this->_arrData = $arrData;
}
public function getData() {
return $this->_arrData;
}
}
/**
* @brief: 事件处理器可以是一个函数
*/
function handler(Form $form, FormEventArgs $args) {
echo get_class($form)."n";
print_r($args->getData());
echo "I am return true onsubmit, so form can submitn";
return true;
}
/**
* @brief: 一个页面类,演示了如何使用实现了事件机制的类
*/
class Page {
public function show() {
$f = new Form();
$f->addEventHandler("onsubmit","handler"); // 这里可以使一个全局函数
$f->submit("action.php");
echo "n";
$f2 = new Form();
$f2->addEventHandler("onsubmit",array($this,"Form_onsubmit")); // 这里可以使用任意的方法名
$f2->submit("action.php");
}
/**
* @brief: 事件处理器也可以是对象的一个方法
*/
public function Form_onsubmit(Form $form, FormEventArgs $args) {
echo get_class($form)."n";
print_r($args->getData());
echo "I am return false onsubmit, so form can not submitn";
return false;
}
}
// test
$p = new Page();
$p->show();
?>
相关参考:
http://hi.baidu.com/wwwanq/blog/item/0778458033d417d1bd3e1ed4.html
http://www.phpres.com/html/PHPjichujiaocheng/20080628/1980.html