今天在看框架,看到入口bootstrap文件.这个是一个工厂类模式,通过option来创建对应的object.
负责实例具体对象的那个工厂方法大致是这样的:

class bootstrap {
...
public static function &factory($options = array()) {

        if (!(self::$_instance instanceof self)) {

            if ($options['interface'] == 'web') {
                $interface = 'Web';
            } else if ($options['interface'] == 'cli') {
                $interface = 'Cli';
            } 
        }
        self::$_instance = new $interface();

        return self::$_instance;
    }
...
}

继续阅读

file_put_contents() 函数

定义和用法
file_put_contents() 函数把一个字符串写入文件中。
与依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
当访问一个文件是,函数必须遵循下面这些法则:

  1. 如果设置了FILE_USE_INCLUDE_PATH,那么将检查*filename*副本的内置路径
  2. 如果文件不存在,将创建一个文件
  3. 打开文件
  4. 如果设置了LOCK_EX,那将对文件上锁
  5. 如果设置了FILE_APPEND,那么将移至文件末尾;否则的话,将会清除文件的内容
  6. 向文件中写入数据
  7. 关闭文件并对所有文件解锁

继续阅读

双冒号操作符即作用域限定操作符Scope Resolution Operator可以访问静态、const和类中重写的属性与方法。
在类定义外使用的话,使用类名调用。在PHP 5.3.0,可以使用变量代替类名。
Program List:用变量在类定义外部访问

    
< ?php
class Fruit {
    const CONST_VALUE = 'Fruit Color';
}

$classname = 'Fruit';
echo $classname::CONST_VALUE; // As of PHP 5.3.0

echo Fruit::CONST_VALUE;
?>

继续阅读

PHP SESSION原理

我们知道,session是在服务器端保持用户会话数据的一种方法,对应的cookie是在客户端保持用户数据。HTTP协议是一种无状态协议,服务器响应完之后就失去了与浏览器的联系,最早,Netscape将cookie引入浏览器,使得数据可以客户端跨页面交换,那么服务器是如何记住众多用户的会话数据呢?

首先要将客户端和服务器端建立一一联系,每个客户端都得有一个唯一标识,这样服务器才能识别出来。建议唯一标识的方法有两种:cookie或者通过GET方式指定。默认配置的PHP使用session的时会建立一个名叫”PHPSESSID”的cookie(可以通过php.ini修改session.name值指定),如果客户端禁用cookie,你也可以指定通过GET方式把session id传到服务器(修改php.ini中session.use_trans_sid等参数)。

我们查看服务器端session.save_path目录会发现很多类似sess_vv9lpgf0nmkurgvkba1vbvj915这样的文件,这个其实就是session id “vv9lpgf0nmkurgvkba1vbvj915″对应的数据。真相就在这里,客户端将session id传递到服务器,服务器根据session id找到对应的文件,读取的时候对文件内容进行反序列化就得到session的值,保存的时候先序列化再写入。

继续阅读

由于微博中有字数限制,所以如果你发的是网址,会自动将其变为短网址。之前我的几篇文章介绍了如何将网址转为短网址,这里我们反过来,把短网址还原为实际网址。请参照下面的程序,用PHP实现:

< ?php
$url = "http://t.cn/hbX7t7";
echo unshorten($url);

function unshorten($url) 
{
	$url = trim($url);
	$headers = get_headers($url);
  	$location = $url;
  	$short = false;
  	foreach($headers as $head) 
	{
    	if($head=="HTTP/1.1 302 Found") 
			$short = true;
    	if($short && startwith($head,"Location: ")) 
		{
      		$location = substr($head,10);
    	}
  	}
  	return $location;
}

function startwith($Haystack, $Needle)
{
	return strpos($Haystack, $Needle) === 0;
}
?>

继续阅读

关于php的引用(就是在变量或者函数、对象等前面加上&符号)的作用,我们先看下面这个程序。

    
< ?php
$a = 100; //声明变量a
$b = &$a; //声明变量b,引用自变量a
echo "$a 
"; echo "$b
"; $a++; //变量a自增1 echo "$a
"; echo "$b
";//查看变量b,也增加了1,说明使用的是同一存储单元 ?>

继续阅读

在PHP里,想要得到所有的HTTP请求头,可以使用getallheaders方法,不过此方法并不是在任何环境下都存在,比如说,你使用fastcgi方式运行PHP的话,就没有这个方法,所以说我们还需要考虑别的方法,幸运的是$_SERVER里有我们想要的东西,它里面键名以HTTP_开头的就是HTTP请求头:

$headers = array();
foreach ($_SERVER as $key => $value) {
if ('HTTP_' == substr($key, 0, 5)) {
$headers[str_replace('_', '-', substr($key, 5))] = $value;
}
}

代码很简单,需要说明的是RFC里明确指出了信息头的名字是不区分大小写的。
继续阅读

 < ?php
 function xml2array($url, $get_attributes = 1, $priority = 'tag')
 {
     $contents = "";
     if (!function_exists('xml_parser_create'))
     {
         return array ();
     }
     $parser = xml_parser_create('');
     if (!($fp = @ fopen($url, 'rb')))
     {
         return array ();
     }
     while (!feof($fp))
     {
         $contents .= fread($fp, 8192);
     }
     fclose($fp);
     xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
     xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
     xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
     xml_parse_into_struct($parser, trim($contents), $xml_values);
     xml_parser_free($parser);
     if (!$xml_values)
         return; //Hmm...
     $xml_array = array ();
     $parents = array ();
     $opened_tags = array ();
     $arr = array ();
     $current = & $xml_array;
     $repeated_tag_index = array (); 
    foreach ($xml_values as $data)
     {
         unset ($attributes, $value);
         extract($data);
         $result = array ();
         $attributes_data = array ();
         if (isset ($value))
         {
             if ($priority == 'tag')
                 $result = $value;
             else
                 $result['value'] = $value;
         }
         if (isset ($attributes) and $get_attributes)
         {
             foreach ($attributes as $attr => $val)
             {
                 if ($priority == 'tag')
                     $attributes_data[$attr] = $val;
                 else
                     $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
             }
         }
         if ($type == "open")
         { 
            $parent[$level -1] = & $current;
             if (!is_array($current) or (!in_array($tag, array_keys($current))))
             {
                 $current[$tag] = $result;
                 if ($attributes_data)
                     $current[$tag . '_attr'] = $attributes_data;
                 $repeated_tag_index[$tag . '_' . $level] = 1;
                 $current = & $current[$tag];
             }
             else
             {
                 if (isset ($current[$tag][0]))
                 {
                     $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                     $repeated_tag_index[$tag . '_' . $level]++;
                 }
                 else
                 { 
                    $current[$tag] = array (
                         $current[$tag],
                         $result
                     ); 
                    $repeated_tag_index[$tag . '_' . $level] = 2;
                     if (isset ($current[$tag . '_attr']))
                     {
                         $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                         unset ($current[$tag . '_attr']);
                     }
                 }
                 $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
                 $current = & $current[$tag][$last_item_index];
             }
         }
         elseif ($type == "complete")
         {
             if (!isset ($current[$tag]))
             {
                 $current[$tag] = $result;
                 $repeated_tag_index[$tag . '_' . $level] = 1;
                 if ($priority == 'tag' and $attributes_data)
                     $current[$tag . '_attr'] = $attributes_data;
             }
             else
             {
                 if (isset ($current[$tag][0]) and is_array($current[$tag]))
                 {
                     $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                     if ($priority == 'tag' and $get_attributes and $attributes_data)
                     {
                         $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                     }
                     $repeated_tag_index[$tag . '_' . $level]++;
                 }
                 else
                 {
                     $current[$tag] = array (
                         $current[$tag],
                         $result
                     ); 
                    $repeated_tag_index[$tag . '_' . $level] = 1;
                     if ($priority == 'tag' and $get_attributes)
                     {
                         if (isset ($current[$tag . '_attr']))
                         { 
                            $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                             unset ($current[$tag . '_attr']);
                         }
                         if ($attributes_data)
                         {
                             $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                         }
                     }
                     $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
                 }
             }
         }
         elseif ($type == 'close')
         {
             $current = & $parent[$level -1];
         }
     }
     return ($xml_array);
 }
 ?>
 

继续阅读