css扒皮

Time:2011-01-20 11:08:50. Author:millken. Category:技术.
根据dom结构,采集所需的样式

利用firebug的控制台来调试PHP程序

Time:2010-11-03 15:37:31. Author:millken. Category:技术. Tags:firebug,debug.
利用set_error_handler来捕捉错误,并将错误显示在firebug控制台内,这样代替print输出错误

a small php template class

Time:2010-09-06 12:04:51. Author:millken. Category:技术.

/**
 * MyBlogAdmin Blog Platform
 *
 * @author     millken
 * @copyright  Copyright (c) 2010 MyBlogAdmin
 * @license    GNU General Public License 2.0
 * @version    $Id: template.class.php 11 2010-06-14 15:13:17Z millken $
 */
/**
 * common of template
 * plugin by yourself
 *
 */
define('TEMPLATE_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
/* plugin path */
define('TEMPLATE_PLUGIN_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR . 'template_plugin' . DIRECTORY_SEPARATOR);

class Template {
    public $ldel = "{";
    public $rdel = "}";
    public $template_dir = './templates/';
    public $compile_dir = './template_c/';
    public $compress = false;
    public $debug = false;
    public $_temp_key = array();
    public $_temp_val = array();
    static $version = '20100712';
    public function __construct() {
        $this->start_time = microtime(true);
    }
    public function __destruct(){
        unset($this->_vars);
    }
    public function assign( $tpl_var, $value = null) {
        if (is_array($tpl_var)) {
            foreach ($tpl_var as $_key => $_val) {
                if ($_key != '') {
                    $this->_vars[$_key] = is_array($_val)?$this->arrayToObject($_val):$_val;
                }
            }
        } else {
            if ($tpl_var != '') {
                $this->_vars[$tpl_var] = is_array($value)?$this->arrayToObject($value):$value;
            }
        }
    }
    private function arrayToObject($array) {
        if(!is_array($array)) {
            return $array;
        }
        $object = new stdClass();
        if (is_array($array) && count($array) > 0) {
          foreach ($array as $name=>$value) {
             $name = strtolower(trim($name));
             if (isset($name)) {
                $object->$name = $this->arrayToObject($value);
             }
          }
          return $object;
        }else{
          return FALSE;
        }
    }
    public function fetch( $templatename ) {
        $compilefile = $this->compile_dir . $templatename . '.php';
        $nowtime = $this->getDifftime($templatename);
        if( is_file($compilefile) && $this->debug == false ) {
            $content = file_get_contents( $compilefile );
            $oldtime = substr($content, 8, strpos($content,"*/") - 8);
            if( intval($oldtime) == $nowtime)
            return $this->_eval($content);
        }else{
            if(false == touch($compilefile))
            throw new Exception ("the compiled file: $compilefile unable writed!");
        }
        $content = $this->fetch_source( $templatename );
        $content = preg_replace(
            array('/\?>/','/<\?([php])/i',"/{$this->ldel}([^\{$this->rdel}\{$this->ldel}\n]*){$this->rdel}/e"),
            array('?>','<?\1',"\$this->doParse('\\1');"),
            $content );
        //die($content);
        $head = '';
        file_put_contents($compilefile , $head . $content);
        $content = $this->_eval($content);
        return $content;
    }

    public function display( $filename, $output = true ) {
        $content = $this->fetch($filename);
        if($this->compress)
            $content = preg_replace(array("~>\s+\r~","~>\s+\n~","~>\s+<~"),    array(">",">","><"),$content);
        $this->time = sprintf('%.4f', microtime(true) - $this->start_time);
        if($output)die($content);
        return $content;
    }

    protected function _eval( $content ) {
        ob_start();
        eval('?' . '>' . trim($content));
        $content = ob_get_contents();
        ob_end_clean();
        return $content;
    }

    protected function doParse( $tag ) {
        $tag = stripslashes(trim($tag));

        if (empty($tag)) {
            return '{}';
        }elseif($tag{0} == '*' && substr($tag, -1) == '*') { // 注释部分
            return '';
        }elseif($tag{0} == '$'){ // variable
            $tags = explode('.',substr($tag,1));
            $var = array_shift($tags);
            $vart = '';
            if(!empty($tags)) {
                $vart = '->' . implode('->', $tags);
            }
            return '_vars[\'' . $var . '\']' . $vart . '; ?>';
        }elseif($tag{0} == '/'){ // end tag
            $plug = 'End' . substr($tag, 1) ;
        }else{
            $plug = array_shift(explode(' ', $tag));
        }

        $plugin = self::loadPlugin($plug);
        if(!$plugin)return '{ '. $tag .' }';
        return $plugin->compile($tag);

    }

    private function push_vars($key, $val)    {
        if (!empty($key))
            array_push($this->_temp_key, "\$this->_vars['$key']='" .$this->_vars[$key] . "';");
        if (!empty($val))
            array_push($this->_temp_val, "\$this->_vars['$val']='" .$this->_vars[$val] . "';");
    }

    private function pop_vars() {
        $key = array_pop($this->_temp_key);
        $val = array_pop($this->_temp_val);

        if (!empty($key))eval($key);
    }

    public function fetch_source( $filename ) {
        $file = $this->template_dir . $filename;
        if(is_file( $file )) {
            return file_get_contents( $file );
        }else{
            throw new Exception ('template \'' . $filename . '\'not exists!');
        }
    }

    public function loadPlugin($plugin_name)    {
        $classname = 'Template_Plugin_' . ucfirst(strtolower($plugin_name));
        if (class_exists($classname, false) && method_exists('Template_Plugin','compile'))
        return new $classname;

        $filename = TEMPLATE_PLUGIN_DIR . strtolower($classname) . '.php';
        if(is_file($filename)) {
            include_once ($filename);
            return new $classname;
        }
        return false;
    }
    private function mkdir( $path ) {
        return is_dir($path) or (self::mkdir(dirname($path)) and mkdir($path, 0777));
    }
    private function getDifftime($templatefile) {
        return filemtime($this->template_dir . $templatefile);
    }
    public function setDelimiter($left_delimiter, $right_delimiter) {
        $this->ldel = $left_delimiter;
        $this->rdel = $right_delimiter;
    }
    public function setCompress( $is_compress = false ) {
        $this->compress = $is_compress;
    }
    public function setCompileDir ( $dir, $makedir = false ) {
        if($makedir)self::mkdir($dir);
        $this->compile_dir = $dir;
    }
    public function setTemplateDir( $dir ) {
        if(!is_dir($dir)) throw new Exception ("the directory : $dir not exists!");
        $this->template_dir = $dir . DIRECTORY_SEPARATOR;
    }
}

/*
 * interface for template's plugin
 */
interface Template_Plugin {
    public function compile($tag);
}
class Template_Plugin_Foreach implements Template_Plugin {
    function compile($tag) {
        preg_match_all("/foreach\s+\\$([\w\.]+)\s+as\s+(\\$(\w+)\s*$|\\$(\w+)\s*=>\s*\\$(\w+)$)/i", $tag, $var );
        //print_r($var);
        $key = $val = $output = '';
        if( $var[3][0] ) {
            $key = trim( $var[3][0] );
            $as = '$this->_vars[\''. $key .'\']';
        }elseif( $var[4][0] && $var[5][0] ) {
            $key = trim( $var[4][0] );
            $val = trim( $var[5][0] );
            $as = '$this->_vars[\'' . $key . '\'] => $this->_vars[\'' . $val . '\']';
        }
        $tags = explode('.',$var[1][0]);
        $var1 = array_shift($tags);
        $vart = '';
        if(!empty($tags)) {
            $vart = '->' . implode('->', $tags);
            $token =  '$this->_vars[\'' . $var1 . '\']' . $vart . '';
        }else
            $token = '$this->_vars[\''. $var[1][0] .'\']';
        $output = 'push_vars(\'' . $key .'\', \''. $val .'\'); foreach((array)'. $token .' as '. $as .'){ ?>';
        return $output;
    }

}

class Template_plugin_EndForeach implements Template_Plugin {
    function compile($tag) {
        $output = 'pop_vars(); ?>';
        return $output;
    }
}
class Template_Plugin_If implements Template_Plugin {
    function compile($tag) {
        preg_match_all('/\-?\d+[\.\d]+|\'[^\'|\s]*\'|"[^"|\s]*"|[\$\w\.]+|!==|===|==|!=|<>|<<|>>|<=|>=|&&|\|\||\(|\)|,|\!|\^|=|&|<|>|~|\||\%|\+|\-|\/|\*|\@|\S/', $tag, $match);
        $tokens = $match[0];
        //允许使用的函数列表
        $functionlist = array('strtolower','strtoupper','strlen','urldecode','in_array','array_exists','array_keys','array_values');
        unset($tokens[0]);
        for ($i = 1, $count = count($tokens); $i < $count; $i++) {
            $token = &$tokens[$i];
            switch (strtolower($token)) {
                case 'eq':$token = '==';break;
                case 'ne':break;
                case 'neq':$token = '!=';break;
                case 'lt':$token = '<';break;
                case 'le':break;
                case 'lte':$token = '<=';break;
                case 'gt':$token = '>';break;
                case 'ge':break;
                case 'gte':$token = '>=';break;
                case 'and':$token = '&&';break;
                case 'or':$token = '||';break;
                case 'not':$token = '!';break;
                case 'mod':$token = '%';break;
                default:
                    if ($token[0] == '$') {
                        $tags = explode('.',substr($token, 1));
                        $var = array_shift($tags);
                        $vart = '';
                        if(!empty($tags)) {
                            $vart = '->' . implode('->', $tags);
                            $token =  '$this->_vars[\'' . $var . '\']' . $vart . '';
                        }else
                            $token = '$this->_vars[\''. substr($token, 1) .'\']';
                    }elseif(function_exists($token) && !in_array($token, $functionlist))
                    throw new Exception('can\'t use function:'.$token.'');
                break;
            }
        }
        return $this->output($tokens);
    }

    function output($tokens) {
        return '';
    }
}

class Template_Plugin_Elseif extends Template_Plugin_If  {
    function output($tokens) {
        return '';
    }

}

class Template_plugin_Else implements Template_Plugin {
    function compile($tag) {
        $output = '';
        return $output;
    }
}
class Template_plugin_EndIf implements Template_Plugin {
    function compile($tag) {
        $output = '';
        return $output;
    }
}
class Template_Plugin_Include implements Template_Plugin {
    function compile($tag) {
        $file = preg_replace('/include\s*file\=["\']?\s*([a-zA-Z0-9_.\/]+)\s*[\'"]?\s*/is', '\\1', $tag );
        return 'fetch(' . "'$file'" . '); ?>';
    }
}

jquery简单实现图片自动缩放

Time:2010-07-28 04:08:04. Author:millken. Category:技术. Tags:作品,jquery.
$(document).ready(function() {
    $('img[data^=maxsize_]').each(function(){
        var t = this;
        var autoScaling = function() {
            var size = $(t).attr('data').substring(8);
            wh=size.split("*");
            wh1 = isNaN(wh[1])?wh[0]:wh[1];
            max = Math.max(t.width/wh[0], t.height/wh1);
            if(max>1)$(t).css({'width':t.width/max,'height':t.height/max});
        }
        if(this.complete)autoScaling();
        $(this).load(function(){autoScaling();
        });
    });
});

调用上面代码后,只要img含有类似data="maxsize_300*200",就可以实现自动缩放。

javascriptErrorLogger

Time:2010-07-28 03:00:58. Author:millken. Category:技术.

var JavascriptErrorLogger = {
    initialize: function() {
        window.onerror = JavascriptErrorLogger.onError_handler;
    },

    onError_handler: function(errorMessage, errorUrl, lineNumber) {
        var browserCodeName = navigator.appCodeName;
        var browserAppName = navigator.appName;
        var browserName = navigator.product;
        var browserVersion = navigator.appVersion;
        var browserLanguage = ((typeof (navigator.browserLanguage) != 'undefined') ? navigator.browserLanguage : navigator.language);
        var userPlatform = navigator.platform;
        var userAgent = navigator.userAgent;
        var windowLocationUrl = window.location.href;

        var loggerURL = '/WebServices/ClientLogging.asmx/WriteJavascriptErrorToLog';
        var requestParameters = '?errorMessage=' + encodeURIComponent(errorMessage) + '&errorUrl=' + encodeURIComponent(errorUrl) + '&lineNumber=' + encodeURIComponent(lineNumber) + '&browserCodeName=' + encodeURIComponent(browserCodeName) + '&browserAppName=' + encodeURIComponent(browserAppName) + '&browserName=' + encodeURIComponent(browserName) + '&browserVersion=' + encodeURIComponent(browserVersion) + '&browserLanguage=' + encodeURIComponent(browserLanguage) + '&userPlatform=' + encodeURIComponent(userPlatform) + '&userAgent=' + encodeURIComponent(userAgent) + '&windowLocationUrl=' + encodeURIComponent(windowLocationUrl);

        var webServiceUrl = '' + loggerURL + requestParameters;
        jQuery.ajax({
            type: 'GET',
            url: webServiceUrl,
            dataType: 'text'
        });
    }
};
JavascriptErrorLogger.initialize();



Junction-windows下的符号链接

Time:2010-07-22 03:52:50. Author:millken. Category:技术.

简介

Windows 2000 以及更高版本都支持目录符号链接,其中目录作为到计算机上另一目录的符号链接。例如,如果目录 D:\SYMLINK 指定 C:\WINNT\SYSTEM32 作为其目标,那么访问 D:\SYMLINK\DRIVERS 的应用程序实际上访问的是 C:\WINNT\SYSTEM32\DRIVERS。目录符号链接在 Windows 中称为 NTFS 接合点。遗憾的是,Windows 并没有附带创建接合点的工具,这样您必须要购买 Win2K 资源工具包,其中附带了用于创建接合点的 linkd 程序。因此我决定编写我自己的接合点创建工具: JunctionJunction 不仅允许您创建 NTFS 接合点,还允许您查看文件或目录是否实际为重新分析点。重新分析点是作为 NTFS 接合点基础的机制,它们被 Windows 的远程存储服务 (RSS) 以及卷装入点所使用。

请阅读此 Microsoft KB 文章以获取有关使用接合点的提示。

请注意,Windows 不支持到远程共享上的目录的接合点。

如果您希望查看重新分析信息,Junction 的用法如下所示:

用法:junction [-s] <目录或文件名>

-s

对子目录执行递归操作。

如果您希望创建或删除一个接合点,请按如下方式使用 Junction

用法:junction [-d] <接合点目录> [<接合点目标>]

要删除接合点,请指定 -d 开关以及接合点名称。

下载 Junction (41 KB)

windows下利用BIND实现泛域名解析

Time:2010-03-26 09:57:47. Author:millken. Category:技术. Tags:bind.

MySQL操作常用命令

Time:2010-03-04 02:03:31. Author:millken. Category:技术.

一、操作库

--列出有所有的数据库
mysql> show databases; 

--创建库 例如创建名字为jgcao的库
mysql> create database jgcao;

--使用库 例如使用名字为jgcao的库
mysql> use jgcao;

-- 删除库 例如删除名字为jgcao的库
mysql> drop database jgcao;

二、操作表

--创建表 例如创建表test
mysql> create table test;

--有条件创建表 例如创建表test
mysql> create table if not exists test;

--复制表
mysql> create table new_test select * from test;

--创建临时表 例如创建表test
mysql> create temporary table test;

-- 查看可用表
mysql> show tables;

--查看表结构 例如查看表test的表结构
mysql> show columns in test;

--删除表 例如删除表test
mysql> drop table test ;

--表的详细描述 例如查询表test的描述
mysql> describe tablename;

--修改表结构
mysql> alter table `test` ADD `date` int( 11 ) \
mysql> NOT NULL DEFAULT '0' after `id`;
mysql> alter table `test` change `date` `timestamp` \
mysql> int( 11 ) NOT NULL DEFAULT '0' ;
mysql> alter table `test` drop `date`;

四、数据操作

--增加新行
mysql> INSERT INTO 表名称 VALUES (值1, 值2,....)

--指定列名插入
mysql> INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

--更新修改数据
mysql> UPDATE 表名称 SET 列名称 = 新值,列名称2 = 新值2 WHERE 列名称 = 某值

--删除行
mysql> DELETE FROM 表名称 WHERE 列名称 = 值

--删除所有行
mysql> DELETE FROM table_name;
mysql> DELETE * FROM table_name;

五、查询数据

--查询结果
mysql> SELECT now();

--从数据库中,查询一个列或多个列
mysql> SELECT 列名称 FROM 表名称

--从数据库中,查询全部列
mysql> SELECT * FROM 表名

--返回唯一值,就是不要重复的值
mysql> SELECT DISTINCT 列名称 FROM 表名称

--表联合查询
mysql> SELECT 列名称 FROM 表名称1 [INNER | CROSS | LEFT | OUT] join 表名称2 on 两个表连接条件

--条件查询
mysql> SELECT 列名称 FROM 表名称 WHERE 列 运算符 值

-- =   等于
-- <>   不等于
-- >   大于
-- <   小于
-- >=   大于等于
-- <=   小于等于
-- BETWEEN   在某个范围内
-- LIKE   搜索某种模式
-- AND 与
-- OR 或

--排序语句
mysql> SELECT 列名,列名 FROM 表名 ORDER BY 被排序的列名 DESC(加这句可以降序排列)

--分组语句
mysql> SELECT 列名,列名 FROM 表名 GROUP BY 被排序的列名

--分段查询,offset:开始记录;rows:记录数量
mysql> SELECT 列名,列名 FROM 表名 LIMIT offset,rows

六、修改mysql中root的密码:


--登录mysql
shell> mysql -u root -p

--修改用户密码
mysql> update user set password=password("password") \
mysql> where user=’root’;

--刷新数据库
mysql> flush privileges

七、授权用户


--增加新用户

--格式:
mysql> grant privileges on database[.table] to user@host \
mysql> identified by “password” [WITH GRANT OPTION]
--解释
--privileges 对数据库的操作权限
--database 数据库
--table 表
--user 用户名称
--host 登录主机地址
--password 登录密码
--WITH GRANT OPTION 设定用户是否有授权的权限

--privileges 常用列举
--ALL [PRIVILEGES] 设置除GRANT OPTION之外的所有简单权限
--ALTER 允许使用ALTER TABLE
--CREATE 允许使用CREATE TABLE
--CREATE TEMPORARY TABLES 允许使用CREATE TEMPORARY TABLE
--CREATE USER 允许使用CREATE USER, DROP USER, RENAME USER和REVOKE ALL PRIVILEGES。
--CREATE VIEW 允许使用CREATE VIEW
--DELETE 允许使用DELETE
--DROP 允许使用DROP TABLE
--EXECUTE 允许用户运行已存储的子程序
--FILE 允许使用SELECT...INTO OUTFILE和LOAD DATA INFILE
--INDEX 允许使用CREATE INDEX和DROP INDEX
--INSERT 允许使用INSERT
--LOCK TABLES 允许对您拥有SELECT权限的表使用LOCK TABLES
--SELECT 允许使用SELECT
--SHOW DATABASES SHOW DATABASES显示所有数据库
--SHUTDOWN 允许使用mysqladmin shutdown
--UPDATE 允许使用UPDATE
--GRANT OPTION 允许授予权限

--授权例子

--创建一个可以从任何地方连接服务器的一个完全的超级用户
mysql> grant all privileges on *.* to 'admin'@'%' \
mysql> identified by ’jgcao’ with grant option;

--创建一个用户jgcao在特定客户端192.168.1.108登录,可访问特定数据库lines
mysql> grant select, insert, update, delete, create, drop \
mysql> on lines.* to 'jgcao'@'192.168.1.108' identified by ‘passwd’;

--删除授权:

--格式
--revoke privileges ON database[.table] from user@host
--解释
--privileges 对数据库的操作权限
--database 数据库
--table 表
--user 用户名称
--host 登录主机地址

--删除授权例子

--解除root的所有权限
mysql> revoke all privileges on *.* from 'root'@'%';
mysql> delete from user where user=”root” and host=”%”;
mysql> flush privileges;

单文件缓存类

Time:2010-02-21 21:38:39. Author:millken. Category:技术. Tags:cache.

在10W以内比直接生成单文件的效率提高了一倍

在10W以外,效率直线下降

小巧灵活的WebService

Time:2010-02-05 01:40:46. Author:millken. Category:技术. Tags:webservice,作品.

squid安装测试

Time:2010-01-26 04:25:02. Author:millken. Category:技术. Tags:squid.

inotify+rsync文件实时同步安装配置

Time:2010-01-25 05:44:48. Author:millken. Category:技术. Tags:inotify,rsync.

关于我:

陈震(millken) 男 26岁 高级程序员

湖南石门人,现混迹于上海。

联系方式:millken#gmail.com

开放分类