载入中
自定义HTML载入中... loading
日历
<<  <  2008 - 7  >  >>
Su Mo Tu We Th Fr Sa
    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    
载入中
边栏内容载入中... loading
Mind42 has finished it's beta! [原创 2008-07-12 11:58:47]  
Mind42是一个在线做思维导图的网站,初步用了一下,挺不错的。
转发mind42.com给我的邮件:

Mind42 has finished it's beta!

This is the first newsletter from Mind42, and we've waited for this for a long time to be able to do the following announcement: Mind42 has finished it's beta!

After we've been in beta for over a year now, the introduction of countless new features, a database crash, a server move, and tons of bug fixes we just thought it was about time. Mind42 is stable enough to remove the beta badge.

The most visible change is our revised homepage. We now offer a detailed help and we also optimized the sign in/up pages as well as the general homepage navigation. We hope this is at everyones fancy.

But what does this mean for the users of Mind42? Currently: Nothing changes. We are still working an a paid pro-version of Mind42 - but this doesn't mean that we'll quit the free service of Mind42. More infos will be published when this is getting ready. Also we are still interested in adding new features to Mind42, so please just send any feature requests to info@mind42.com.

Finishing the beta has been an important step on our way to create an easy to use and reliable mind mapping solution for everybody, but definitely not the last one. We still have a long way in front of us containing new features and versions as well as bug fixes. Hence we really appreciate every feedback we can get and will be happy to follow the user wishes and ideas on our way to a better product.

http://www.mind42.com

Unsubscribe

If you no longer wish to receive these emails, please unsubscribe using this unsubscribe link or turn newsletters of at your account managament page.


 

(字节数 : 2373)
Firefox3隆重推出 [原创 2008-06-18 10:00:43]  
期待已久的Firefox3终于隆重推出了,北京时间今天凌晨1点开始是“Firefox下载日”,而且Firefox.com也重定向到了谋志中国。Firefox不只是浏览器,还是一个很有潜力的开发平台,很值得我们研究啊。

另:安装后我同时安装了google toolbar,似乎在证书方面有些问题。Firefox3对Https的证书认证更加严格了,在扩展开发方面也要求做一些修改,其他扩展相应的修改可能还要待一段时间才能跟进。

另:今天是个好日子,重新开始写这个blog。快一年没写了,现在和讯blog的留言功能终于有了一些防垃圾机制,欣慰。

 

(字节数 : 556)
细致学习php5的OO特性[1] [原创 2007-08-22 09:47:17]  

尽管开发和运行环境已经是php5了,但是一直没有使用php5的OO特性写代码。现在终于有机会拿着研究C++ OOP的精神,研究PHP5的OO特性。本文设计到一些细节,有些代码仅仅为了测试,有意为之,不要见笑。

  • This 伪变量。

从PHP手册中看到这样一句话,一开始有些不理解。

$this 是一个到调用对象(通常是方法所属于的对象,但也可以是另一个对象,如果该方法是从第二个对象内静态调用的话)的引用。

 

源文档 <http://php.chinaunix.net/manual/zh/language.oop5.basic.php>

于是做了这样的例子:

<?php
    
class ClassB{
        const 
NAME "Class B";
        public    
$a ClassB::NAME;
        public function 
foo(){
            echo 
$this->a.":: foo call\n";
            echo 
"'this' is a {$this->a} object\n";
        }
    };
    
    class 
ClassA{
    
        const    
NAME "class A";
        public    
$a ClassA::NAME;

        public function 
createB(){
            return new 
ClassB();
        }
        
        public  function 
foo(){
            echo 
$this->a.":: foo call\n";
            
            echo 
"\n\nCall a object function\n";
            
$this->createB()->foo();
            
            echo 
"\n\n function called statically \n";
            
ClassB::foo();

        }
    }

    
$A = new ClassA();
    
$A->foo();

?>

 

发现在ClassA里面直接以ClassB::foo();的形式“静态调用”,ClassB::foo();里面的this的确是对象$A的引用。

 注意是“静态调用(called statically)”而非静态方法。经过测试,静态方法内不允许this伪变量。

  • Extends

上面的特性-- 在方法被静态调用的上下文环境中,this是调用者的引用,这个特性可以应用到多级继承时,提供子类访问基类的途径:

<?php

    
class BaseClass 
    
{
        
// Redefine the parent method
        
public final $abc "Base";
        function 
displayVar()
        {
            echo 
"this->abc:".$this->abc."\n";
            echo 
"Base class\n";
            
parent::displayVar();
        }
    }

    class 
SimpleClass extends BaseClass
    
{
        public 
$abc "SimpleClass";
        
// Redefine the parent method
        
function displayVar()
        {
            echo 
"this->abc:".$this->abc."\n";
            echo 
"SimpleClass class\n";
        }
    }

    class 
ExtendClass extends SimpleClass
    
{
        public 
$abc "ExtendClass";
        
// Redefine the parent method
        
function displayVar()
        {
            echo 
"this->abc:".$this->abc."\n";
            echo 
"Extending class\n";
            
parent::displayVar();
            
BaseClass::displayVar();
        }
    }

    
$extended = new ExtendClass();
    
$extended->displayVar();
?> 


输出:

./test_extends.php

this->abc:ExtendClass

Extending class

this->abc:ExtendClass

SimpleClass class

this->abc:ExtendClass

Base class

  • construct

PHP的__construct不是太严格,甚至允许$obj->__construct , 当然这也可能是为了兼容以前的代码。

但是下面的测试很意外,ClassA::__construct()的调用引起php croe dump了。

<?php
    
class ClassAAA{
        function 
__construct()
        {
            echo 
"ClassA::__construct\n";
        }
    };
    
    
ClassAAA::__construct();
?>

我的php版本:

php -v

PHP 5.2.1 (cli) (built: Apr 28 2007 15:27:26)

Copyright (c) 1997-2007 The PHP Group

Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

  •  destruct

从手册看到一句话:

 

注意: 试图在析构函数中抛出一个异常会导致致命错误。

 

源文档 <http://php.chinaunix.net/manual/zh/language.oop5.decon.php>

这是因为对象的析构时机依赖php的实际实现,可能在php销毁对象的时候,代码块已经不在我们的try catch控制中了。

对于我下面测试的这个版本,php在一个对象的引用计数为0时,立即调用析构函数进行销毁,所以有幸能捕获到析构函数内的异常。

但是手册里面的这个“注意”是对的,因为php没有明确定义析构函数执行的时机,所以我们不应该在析构函数中抛出异常。

<?php

    
class MyDestructableClass {
        function 
__construct() {
            print 
"In constructor\n";
            
$this->name "MyDestructableClass";
        }

        function 
__destruct() {
            print 
"Destroying " $this->name "\n";
            throw new 
Exception("my error");
        }
    }


    function 
abc(){
        try{
        try{
            
$obj = new MyDestructableClass();
            
//return $obj;
        
}
        catch(
Exception $e){
            echo 
"abc::".$e->getMessage();
        }
        }
        catch(
Exception $e){echo "abc::".$e->getMessage();}
        
//echo("abc fun run\n");
    
}

    try{
        
abc();
    }
    catch(
Exception $e){
        echo 
"main::".$e->getMessage();
    }
    
    
    try{
        unset(
$r);
    }
    catch(
Exception $e){
        echo 
"main 2::".$e->getMessage();
    }
    

?>

 

【未完待续】

 

 

(字节数 : 22565)
Recovering vi editor sessions [原创 2007-07-16 10:22:23]  
Freebsd系统启动很慢,提示“ Recovering vi editor sessions:Dec 28 16:41:07 localhost sendmail [339]:My unqual ified host name (localhost)unknown; sleeping for rety”。Google之,发现原因是vi的recover功能需要使用seedmail给用户发邮件。
解决的办法:
rm -rf /var/tmp/vi.recover #清除用户的vi崩溃记录
vim /etc/defaults/rc.conf #设置virecover_enable="NO"&<60;

 

(字节数 : 452)
惊喜----XUL Element Interface [原创 2007-06-07 14:36:13]  

XUL Object Reference  ,只列出了下面几种:

XUL Objects

BoxObject
BrowserBoxObject
EditorBoxObject
IFrameBoxObject
ListBoxObject
MenuBoxObject
PopupBoxObject

ScrollBoxObject
TreeBoxObject
TreeColumn
TreeColumns
TreeContentView
TreeSelection

XULCommandDispatcher
XULControllers
XULDocument
XULElement
XULTemplateBuilder
XULTreeBuilder

而XUL元素那么多,这些Object是远远不够用的了。比如下面的XUL:

 <menulist  id="field-sel" >

<menupopup>

<menuitem label="[null]"/>

</menupopup>

</menulist>

如果我想动态增加几个menuitem元素,那么用XUL DOM提供的API,使用createElement("menuitem") 、appendChild、setAttribute等原始API可以做到:

//先找到item的父元素——menupopup:

  var mups = mlist.getElementsByTagName("menupopup");
  var mup;
  if(!mups.length){
   mup = document.createElement("menupopup");
   mlist.appendChild(mup);
  }
  else{
   mup = mups[0];

//删除所有item:

while(mup.hasChildNodes())mup.removeChild(mup.firstChild);

//添加一个元素:
  var item = document.createElement("menuitem");
  item.setAttribute("label", "[text]");
  item.setAttribute("value", "text");
  mup.appendChild(item);

这样写很麻烦。

于是我抱着一线希望搜索“XULMenulistElement”,WOW,找到了这篇《XUL 1.0》的文档。哈哈,原来真的有XULMenulistElement接口。看:

interface XULMenuListElement : XULSelectControlElement {
  attribute boolean editable;
  attribute boolean open;
  
  attribute DOMString label;
  attribute DOMString crop;
  attribute DOMString image;
  
  // For editable menu lists only.
  readonly attribute XULTextBoxElement inputField;
};

不过并没有提供象HTMLSelectElement那样便捷的操作,别着急,我们再看它继承的接口XULSelectControlElement :

interface XULSelectControlElement : XULControlElement {
  attribute XULSelectControlItemElement selectedItem;
  attribute long selectedIndex;

  attribute DOMString value;
  
  XULSelectControlItemElement appendItem(DOMString label, DOMString value);
  XULSelectControlItemElement insertItemAt(long index, DOMString label, DOMString value);
  XULSelectControlItemElement removeItemAt(long index);
};

看看,这下好了,selectedIndex、appendItem、insertItemAt、removeItemAt,很方便的方法o(∩_∩)o...哈哈。

 经过写代码验证,发现这些属性和方法都是有效的。当通过DOM得到一个menulist元素时,都可以使用上面interface中的属性和方法。但是很奇怪,Mozilla提供了这些接口,也将menulist元素实现了这些接口,却没有将公开这个实现类。上面的代码“<menulist  id="field-sel" >”中,我alert(  document.getElementById("field-sel"))打印出来的还是“ [object XULElement]”,很奇怪。

当然,这篇《XUL 1.0》文档还在建设中,有些接口还没添加进去。比如没有XULTreeElement 接口,发现这里有XULTreeElement接口的文档:

interface XULTreeElement : XULElement {
  readonly attribute NodeList selectedItems;
  readonly attribute NodeList selectedCells;
                  
  void selectItem(in XULElement treeItem);
  void selectCell(in XULElement treeCell);
                  
  void clearItemSelection();
  void clearCellSelection();
                  
  void addItemToSelection(in XULElement treeItem);
  void removeItemFromSelection(in XULElement treeItem);
                  
  void addCellToSelection(in XULElement treeCell);
  void removeCellFromSelection(in XULElement treeCell);
                  
  void toggleItemSelection(in XULElement treeItem);
  void toggleCellSelection(in XULElement treeCell);
                  
  void selectItemRange(in XULElement startItem, in XULElement endItem);
  void selectCellRange(in XULElement startItem, in XULElement endItem);
                  
  void selectAll();
  void invertSelection();
};

也许文档《The XPToolkit Architecture》也值得参考。

一些期待更齐全的文档吧。

 

 

(字节数 : 8512)
firefox 中XMLDocument和string互相转换。 [转贴 2007-05-25 14:09:46]  

尝试了很多方法,包括DOM3的Node::textContent等等,都不行。在xml中textContent属性是过滤标签信息之后的纯文本,类似innerText。

最后还是Google了关键字 javascript "convert xml to string" ,找到这篇文章《Javascript convert XML to string to XML 》,给出了终极方案。


 

Convert XMLDocument to a string in Javascript:

var string = (new XMLSerializer()).serializeToString(xmlobject);
alert(string);

Convert a string to XMLDocument in Javascript:
var xmlstring = '<?xml version="1.0"?>\
<root>\
	<data>\
		<row>\
			<cell>Captain</cell>\
			<cell>Bryophyllum</cell>\
			<cell>Zucchini</cell>\
		</row>\
	</data>\
</root>';
var xmlobject = (new DOMParser()).parseFromString(xmlstring, "text/xml");

 

 

(字节数 : 1168)

继续抓瞎似的摸索。。。

* 执行环境

1. 在overlay.js中的全局位置输出alert(this),结果输出:[object ChromeWindow] , 说明ChromeWindow类型的this对象是firefox扩展javascript的全局环境。(如同html中window对象的是普通script脚本的全局环境。)

2. 另外,全局环境对象的名字也叫window, (如同html中的javascript),在全局访问this和访问window效果是一样的。

3. 从 http://www.xulplanet.com/references/objref/ChromeWindow.html 查ChromeWindow和window的区别,发现类ChromeWindow仅仅比window多实现一个接口----nsIDOMChromeWindow <http://www.xulplanet.com/references/xpcomref/ifaces/nsIDOMChromeWindow.html>

4. 从ChromeWindow文档来看,在扩展中的javascript中访问浏览器当前网页的window对象,需要访问window.content, 访问当前网页中的document需要写成window.content.document.

* extension中的出错处理

1. firefox默认的“java console”不能输出extension中的javascript错误。新版本的“Console”插件( https://addons.mozilla.org/en-US/firefox/addon/1815)弥补了这个缺陷,可以用来检查Chrome错误。

2. window.onerror还是可以工作。这个技巧还可以使用:

window.onerror = function(msg,url,line){
 ACPdebug.onWindowError(msg,url,line);
}

3. 我在《从javascript语言本身谈项目实战》这篇文章中提到的assert和输出stack tree的调试技巧还可以使用。


非常感谢galaxysong对我的耐心指导o(∩_∩)o...哈哈。

 

 

(字节数 : 1757)
firefox的extensions载入过程 [原创 2007-05-24 12:37:18]  

忽然需要开发xul/firefox extension了,一开始什么都不会,真是抓瞎啊。快速浏览了XUL Tutorials ,结果仅仅明白了xul是什么和如何使用它做界面,对于firefox如何载入extensions以及我的extensions中的文件载入、执行先后顺序等细节很少提及。

弄了很久,碰壁n次,总结出如下结论:

 

*  最简单的插件目录结构:

 

  chrome.manifest

  install.rdf

├─content

│   overlay.js

│   overlay.xul

│ 

└─locale

└─en-US

overlay.dtd

 

 

*  firefox的extensions工作方式: 

firefox载入chrome.manifest

对于overlay指令,如:

 

overlay

chrome://browser/content/browser.xul

chrome://my_extension/content/overlay.xul

 

这条指令指定我们自己的overlay.xul“覆盖”系统的browser.xul

 

这样,系统载入自己的browser.xul时,随即载入了我们的overlay.xul

 

我们的overlay.xul里面会有<script>标签,比如引入overlay.js,我们把库代码、启动代码、事件处理函数定义等放到overlay.js中。于是我们的脚本开始工作了。。。

 

overlay.xul里面会定义很多我们自己的界面元素,比如弹出菜单、工具栏、状态栏等。这些元素里面加入我们的事件处理函数,下面的javascript工作方式就和传统javascript差不多了。

 

 

(字节数 : 5071)
卜算子 [原创 2007-05-23 12:17:43]  

 

窗前夜雨稀,
尽碎春梦好。
晓来思量昨日忧,
今晨困意消。
微风青鸟动,
花枝带雨摇。
十里柔情化做雨,
还怕思念少。

 

(字节数 : 163)

    本来用mb_substr就可以的,但是我试着写了替代方案:

<?php

    $a
="五零零+ さす ねむめほ ミムモノサセキゥィァヰン ㄆㄊㄍㄔㄧㄛㄟㄣㄠㄜㄨㄘ"
;
  

    //utf-8 string convent to unicode number array
    //提取utf-8里面的宽字符,转换成unicode原始编码

    
function utf8_to_int($str
)
    {
        
$len strlen($str
);
        
$result = array();  
//unicode number array
        
        
$code 0;            
//unicode number
        
$code_n 0;        
//utf8 byte number

        //01111111 00011111 00001111 00000111 00000011 00000001 
        
static $head_mask = array(0x7f0x1f0x0f0x070x030x01
);
        
        
        for(
$i 0$i $len$i
++)
        {
            
$byte ord$str[$i
] );

            
/* utf8 byte */ 
            
if( ($byte & ~$head_mask[5] ) == 0xfc )        
//6 byte     '1111110x 10xxxxxx ...'
            
{
                
$code_n 6
;
            }
            elseif( (
$byte & ~$head_mask[4] ) == 0xf8 )    
//5 byte    '111110xx 10xxxxxx ...'
            
{
                
$code_n 5
;
            }
            elseif( (
$byte & ~$head_mask[3] ) == 0xf0 )    
//4 byte    '11110xxx 10xxxxxx ...'
            
{
                
$code_n 4
;
            }
            elseif( (
$byte & ~$head_mask[2] ) == 0xe0 )    
//3 byte     '1110xxxx 10xxxxxx ...'
            
{
                
$code_n 3
;
            }
            elseif( (
$byte & ~$head_mask[1] ) == 0xc0 )    
//2 byte     '110xxxxx 10xxxxxx '
            
{
                
$code_n 2
;
            }
            elseif( (
$byte & ~$head_mask[0] ) == 0x00 )    
//1 byte utf8 (ansi byte) '0xxxxxxx'
            
{
                
$code_n 1
;
            }
            else                                        
//other encoding byte (no utf8)
            
{
                
//error byte
                
printf("error($i):0x%02x\n"$byte
);
                continue;
            }
            
            
//echo( "\n$i,$code_n:{". substr($str, $i, $code_n) ."}\n" );
            
            
$code $byte $head_mask[$code_n-1
];
            
//$code <<= 
            
for($j 0$j $code_n-1$j
++)
            {
                
$code <<= 6
;
                
$code |= ord$str[$i $j 1] ) & 0x3f 
;
            }
            
$i += $code_n-1
;
            
$result[] = $code
;
        }
    }

    
        
    
    
    
//$a = "中国";    
    
for($i=0$i<strlen($a); $i
++)
    {
        
printf("%2x "ord($a[$i
]) );
    }
    
utf8_to_int($a
);
?>

 

(字节数 : 18933)
mb_ereg 如何匹配全部? [原创 2007-04-29 14:20:08]  

        mbstring为宽字符提供了mb_ereg/mb_eregi/mb_ereg_search*等函数来替代preg_match/ereg等函数。但是并没有实现类似preg_match_all之类的函数。而是通过mb_ereg_search*系列函数来间接实现匹配全部的功能。

       参考下面的代码:

<?php
    $str = "中国abc + abc ?!?!字符# china string";

    $reg = "\w+";    //匹配全部单词不需要(\w+)*来实现重复匹配
                            //而是通过mb_ereg_search循环得到匹配结果

    mb_regex_encoding("UTF-8");

    mb_ereg_search_init($str, $reg);
    $r = mb_ereg_search();

    if(!$r)
    {
        echo "null\n";
    }
    else
    {
        $r = mb_ereg_search_getregs();  //get first result
        do
        {
            var_dump($r[0]);
            $r = mb_ereg_search_regs(); //get next result
        }
        while($r);
    }
?>

 

 

(字节数 : 1642)

搞懂之后,发现只需要在A上输入下面几个命令:

ssh-keygen -t rsa #输入一个不同于登陆密码的密码
scp .ssh/id_rsa.pub  hostname_B:/home/youruser/.ssh/authorized_keys
exec /usr/bin/ssh-agent $SHELL
ssh-add #输入刚才那个密码


 

 

(字节数 : 221)
1 | 2 | 3 | 4 | 5 | ... 11 | 下一页
和讯个人门户 v1.0 | 和讯部落 | 客服中心