codeigniter对数据库的常用操作

2 ==================================
3 查询
4 $query = $this->db_query("SELECT * FROM table");
5 ==================================
6 */
7
8 //result() 返回对象数组
9 $data = $query->result();
10
11 //result_array() 返回数据
12 $data = $query->result_array();
13
14 //row() 只返回一行对象数组
15 $data = $query->row();
16
17 //num_rows() 返回查询结果行数
18 $data = $query->num_rows();
19
20 //num_fields() 返回查询请求的字段个数
21 $data = $query->num_fields();
22
23 //row_array() 只返回一行数组
24 $data = $query->row_array();
25
26 //free_result() 释放当前查询所占用的内存并删除关联资源标识
27 $data = $query->free_result();
28
29 /*
30 ==================================
31 插入操作
32 ==================================
33 */
34
35 //上次插入操作生成的ID
36 echo $this->db->insert_id();
37
38 //写入和更新操作被影响的行数
39 echo $this->db->affected_rows();
40
41 //返回指定表的总行数
42 echo $this->db->count_all('table_name');
43
44 //输出当前的数据库版本号
45 echo $this->db->version();
46
47 //输出当前的数据库平台
48 echo $this->db->platform();
49
50 //返回最后运行的查询语句
51 echo $this->db->last_query();
52
53 //插入数据,被插入的数据会被自动转换和过滤,例如:
54 //$data = array('name' => $name, 'email' => $email, 'url' => $url);
55 $this->db->insert_string('table_name', $data);
56
57 /*
58 ==================================
59 更新操作
60 ==================================
61 */
62
63 //更新数据,被更新的数据会被自动转换和过滤,例如:
64 //$data = array('name' => $name, 'email' => $email, 'url' => $url);
65 //$where = "author_id = 1 AND status = 'active'";
66 $this->db->update_string('table_name', $data, $where);
67
68 /*
69 ==================================
70 选择数据
71 ==================================
72 */
73
74 //获取表的全部数据
75 $this->db->get('table_name');
76
77 //第二个参数为输出条数,第三个参数为开始位置
78 $this->db->get('table_name', 10, 20);
79
80 //获取数据,第一个参数为表名,第二个为获取条件,第三个为条数
81 $this->db->get_where('table_name', array('id'=>$id), $offset);
82
83 //select方式获取数据
84 $this->db->select('title, content, date');
85 $data = $this->db->get('table_name');
86
87 //获取字段的最大值,第二个参数为别名,相当于max(age) AS nianling
88 $this->db->select_max('age');
89 $this->db->select_max('age', 'nianling');
90
91 //获取字段的最小值
92 $this->db->select_min('age');
93 $this->db->select_min('age', 'nianling');
94
95 //获取字段的和
96 $this->db->select_sum('age');
97 $this->db->select_sum('age', 'nianling');
98
99 //自定义from表
100 $this->db->select('title', content, date');
101 $this->db->from('table_name');
102
103 //查询条件 WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
104 $this->db->where('name', $name);
105 $this->db->where('title', $title);
106 $this->db->where('status', $status);
107
108 //范围查询
109 $this->db->where_in('item1', 'item2');
110 $this->db->where_not_in('item1', 'item2');
111
112 //匹配,第三个参数为匹配模式 title LIKE '%match%'
113 $this->db->like('title', 'match', 'before/after/both');
114 $this->db->not_like();
115
116 //分组 GROUP BY title, date
117 $this->db->group_by('title', 'date');
118
119 //限制条数
120 $this->db->limit(0, 20);

php函数unserialize数据返回false问题分析(转帖)

php函数unserialize数据返回false问题分析

作者:朦朧中的罪惡 发布于:2010-2-1 15:22 Monday 分类:PHP

unserialize的这个问题是由一个emlog论坛用户在使用时报错而发现的

问题表现情况如下:

emlog缓存的保存方式是将php的数据对象(数组)序列化(serialize)后以文件的形式存放,读取缓存的时候直接反序列化(unserialize)缓存字符串即可读取数据,关于序列化和反序列化的原理请看我先前的文章《php函数serialize()与unserialize()不完全研究》

我从用户那里取到的缓存的序列化数据为:

a:1:{s:8:”kl_album”;a:4:{s:5:”title”;s:12:”精彩瞬 间”;s:3:”url”;s:41:”http://www.kaisay.cn/?plugin=kl_album”;s:8:”is_blank”;s:7:”_parent”;s:4:”hide”;s:1:”n”;}}

咋一看了解序列化的人都会说,这个数据很正常啊,没什么问题呢。可是直接把这段字符串进行unserialize,返回的值却是个False;

代码

var_dump(unserialize(‘a:1:{s:8:”kl_album”;a:4:{s:5:”title”;s:12:”精彩瞬间”;s:3:”url”;s:41:”http://www.kaisay.cn/?plugin=kl_album”;s:8:”is_blank”;s:7:”_parent”;s:4:”hide”;s:1:”n”;}}’));

点击查看原图

运行结果

点击查看原图

问题出在哪里呢?答案是 s:41:”http://www.kaisay.cn/?plugin=kl_album”

序列化字符串中标定该字符串http://www.kaisay.cn/?plugin=kl_album的长度是41,可是我们自己数一下却只有37个字符。就是因为这个问题,导致php反序列化字符串失效。

如果将字符串长度改成37,那么程序就会顺利的反序列化

代码:

var_dump(unserialize(‘a:1:{s:8:”kl_album”;a:4:{s:5:”title”;s:12:”精彩瞬 间”;s:3:”url”;s:37:”http://www.kaisay.cn/?plugin=kl_album”;s:8:”is_blank”;s:7:”_parent”;s:4:”hide”;s:1:”n”;}}’));

点击查看原图

通过google后才发现,这个问题国外已经很多的网友遇到了,在官方手册unserialize函数页面的评论中就有很多网友在讨论和研究这个问题的解决方案。

这种情况发生的原因有多种可能,最大的可能就是在序列化数据的时候的编码和反序列化时的编码不一样导致字符串的长度出现偏差。例如数据库编码latin1和UTF-8字符长度是不一样的。

解决方案:

自己用php来纠正序列化字符串中字符串长度的问题,链接

<?php
$unserialized
= preg_replace('!s:(\d+):"(.*?)";!se',"'s:'.strlen('$2').':\"$2\";'", $unserialized );
?>

另外一个网友提出一个在非utf-8情况下的BUG链接

# ascii字符 "\0" 被解析成了 '\0' (\0在C中是字符串的结束符等于chr(0),错误解析后算了2个字符)

// 这么写会出问题
$error = preg_replace('!s:(\d+):"(.*?)";!se',"'s:'.strlen('$2').':\"$2\";'", $unserialized );

// 这么写就没事
$works = preg_replace('!s:(\d+):"(.*?)";!se','"s:".strlen("$2").":\"$2\";"', $unserialized );

// 根据上面的情况我写出的测试例子(注意代码必须用asc格式保存运行)
$test = ‘s:7:”hahaha’. chr(0) .'”;’;
echo preg_replace(‘!s:(\d+):”(.*?)”;!se’, “‘s:’.strlen(‘$2′).’:\”$2\”;'”, $test );
echo ‘<br>’;
echo preg_replace(‘!s:(\d+):”(.*?)”;!se’, ‘”s:”.strlen(“$2″).”:\”$2\”;”‘, $test );
echo ‘<br>’;
echo unserialize(preg_replace(‘!s:(\d+):”(.*?)”;!se’, “‘s:’.strlen(‘$2′).’:\”$2\”;'”, $test ));
echo ‘<br>’;
echo unserialize(preg_replace(‘!s:(\d+):”(.*?)”;!se’, ‘”s:”.strlen(“$2″).”:\”$2\”;”‘, $test ));

下图是运行结果:很显然chr(0) 变成了 \0

点击查看原图
还有一个情况就是单双引号也会出现长度计算错误的问题:链接

<?php
//--------------------------------------------
// 请看例子的值. 数据从来那里来都没有关系,无论是数据库还是代码中
$heightoptionslist = <<<HEIGHTEND
a:3:{s:37:"Hands/inches (eg. 13&#039; 2&quot;HH)";s:6:"option";s:25:"Inches only (eg.39&quot;)";s:6:"option";s:24:"Centimeters (eg. 153cms)";s:6:"option";}
HEIGHTEND;
//--------------------------------------------
// 将序列化的字符串转换回数组
$heightoptionslist = unserialize($heightoptionslist);
//--------------------------------------------
// 打印值,我们可以很容易看懂
echo "<div><pre>\$heightoptionslist = [\n".print_r($heightoptionslist,true)."\n]</pre></div>";
?>

当字符串中带有没有转换的引号的时候,就会出问题了:

<?php
//--------------------------------------------
// 另外一个例子,
// 这次有没有转换过的引号在里面
$heightoptionslist = <<<HEIGHTEND
a:3:{s:26:"Hands/inches (eg. 13\' 2\"HH)";s:6:"option";s:20:"Inches only (eg.39\")";s:6:"option";s:24:"Centimeters (eg. 153cms)";s:6:"option";}
HEIGHTEND;
//--------------------------------------------
//
将序列化的字符串转换回数组.
$heightoptionslist = unserialize($heightoptionslist);
//--------------------------------------------
// 返回了一个空的结果.
echo "<div><pre>\$heightoptionslist = [\n".print_r($heightoptionslist,true)."\n]</pre></div>";
?>

以上两端代码运行结果:

点击查看原图
在字符串还有\r字符的时候计算字符串的长度的时候也会出现问题:链接

When dealing with a string which contain "\r", it seems that the length is not evaluated correctly. The following solves the problem for me :

<?php
// remove the \r caracters from the $unserialized string
$unserialized = str_replace("\r","",$unserialized);

// and then unserialize()
unserialize($unserialized);
?>

总结:解决方案

UTF-8

function mb_unserialize($serial_str) {
$serial_str= preg_replace(‘!s:(\d+):”(.*?)”;!se’, “‘s:’.strlen(‘$2′).’:\”$2\”;'”, $serial_str );
$serial_str= str_replace(“\r”, “”, $serial_str);
return unserialize($serial_str);
}

ASC

function asc_unserialize($serial_str) {

$serial_str = preg_replace('!s:(\d+):"(.*?)";!se','"s:".strlen("$2").":\"$2\";"', $serial_str );
$serial_str= str_replace(“\r”, “”, $serial_str);
return unserialize($serial_str);
}

希望本文能给所有遇到该问题的朋友一点帮助

sublime text 2

此帖转于 http://cloudbbs.org/forum.php?mod=viewthread&tid=3620

大家好,今天给大家分享一款编辑器:sublime text2
我用过很多编辑器,
EditPlus、EmEditor、Notepad++、Notepad2、UltraEdit、Editra、Vim,还有包括netbeans , zendstudio, dreamweaver 等。 最后我遇见了sublime text。  sublime是我见过的最好的编辑器,大型IDE能实现的功能, 用sublime装上相应插件,都能实现。 它是一个小型编辑器, 运行速度很快。现在是鼓起勇气换掉你以前编辑器的时候了。如果你以前没有听说过sublime, 可以看看这个介绍视频:http://v.youku.com/v_show/id_XMzU5NzQ5ODgw.html

sublime本身功能有限,我们需要装上一些插件使其变得强大。sublime在各个操作系统下都可以运行,但在linux下运行需要注意中文输入的问题。 下面我主要介绍一下常用插件、配置的建议以及在linux下运行的注意事项。

一,常用插件

1,package control。 我们用sublime几乎都会首先安装这个插件,这个插件是管理插件的功能,先安装它,再安装其他插件就方便了。  安装方法:
点击sublime的菜单栏 view->show console ;现在打开了控制台, 这个控制台有上下两栏, 上面一栏会实时显示sublime执行了什么插件,输出执行结果, 如果你安装的某个插件不能正常运行,应该先在这里看看有没有报错。下面栏是一个输入框,可以运行python代码。我们输入下面的代码点击回车运行, 就能安装好package control了。

  1. import urllib2,os;pf=’Package Control.sublime-package’;ipp=sublime.installed_packages_path();os.makedirs(ipp) if not os.path.exists(ipp) else None;open(os.path.join(ipp,pf),’wb’).write(urllib2.urlopen(‘http://sublime.wbond.net/’+pf.replace(‘ ‘,’%20’)).read())

复制代码


然后我们按住 ctrl+shift+p。此时会输出一个输入框, 输入install。  选择package contrl: install package 回车 ,需要稍定一会儿,右下角状态栏会显示正在连接的提示文字。 使用sublime时注意看右下角状态栏,很多插件的提示信息都显示在这里,这个状态栏很小,初次使用的人都有可能没有注意到它。

稍等一会儿后,它会出现一个插件列表, 你也可以在输入框中输入文字进行搜索插件。 搜索到自己想安装的插件,再选择它,回车。 就自动给你安装好了。

如果要卸载插件, ctrl+shift+p 输入 remove, 选择package control:remove package 然后再选择已安装的插件, 回车即可卸载。

如果package control 安装插件时失败了, 我们可以采用手动安装的方式, 在google上去搜索插件, 下载插件的源代码。在sublime的菜单栏点击 preferences->Browse package..  此时会打开插件目录。然后把你下载的插件源代码复制进去就可以了。

ctrl+shift+p 打开的输入框面板是什么? 英文叫做 “Anything panel” ,任何操作都可以在这个面板里面完成。我暂且翻译为“万能面板”。 打开万能面板有几种方式。
ctrl+shift+p 打开时,我们需要在面板中输入一个命令,然后执行命令。所有菜单栏能操作事都可以在这里输入命令进行操作。
ctrl+p 打开时,能快速查找文件。
ctrl+r 打开时, 能查找当前文件中的函数。
ctrl+g 打开时,能跳转到指定行。

大家开始接触sublime时对它的环境还不是很熟悉,所有我在这里说得有点多, 简单总结一下前面说的。

控制台的作用: 可以在这里执行python代码,和查看一些执行结果,如果插件运行不正常,可以在这里看看有没有报错。
右下角状态栏: 很多提示信息都会显示在那里,注意经常查看。
万能面板:所有的操作都可以在这里进行,又可以在这里输入命令,又可以在这里查找文件,也可以在这里查找函数等等。
安装插件的方式:除了package control 安装还可以手动安装。

2,ctags。 这个插件能跨文件跳转,跳转到指定函数声明的地方。 使用package control 搜索ctags 进行安装(安装ctags插件就可以了, 还有一个 CTags for PHP 插件没什么用)。注意安装好插件后要需要安装ctags命令。window 下载 ctags.exe http://vdisk.weibo.com/s/7QZd7 。 将ctags.exe文件放在一个环境变量能访问到的地方。打开cmd, 输入ctags,如果有这个命令,证明成功了。 ubuntu下安装运行命令:sudo apt-get install exuberant-ctags 。
然后在sublime项目文件夹右键, 会出现Ctag:Rebuild Tags 的菜单。点击它,然后会生成.tags的文件。

然后在你代码中, 光标放在某个函数上, 点击ctrl+shift+鼠标左键 就可以跳转到函数声明的地方。

3, sublimecodeintel 代码提示。 sublime默认的代码提示只能提示系统函数,用户自己创建的函数、类不能提示。 如果想要提示自己建立的函数。 可以安装sublimecodeintel插件。

sublimecodeintel 安装后需要配置,文件:插件目录/.codeintel/config 中 增加

  1. “PHP”: {
  2. “php”: ‘D:\SaeServer\php\php.exe’,
  3. “phpExtraPaths”: [‘D:\SaeServer\php\stdlib’],
  4. “phpConfigFile”: ‘D:\SaeServer\apache\php.ini’
  5. },

复制代码

配置了php执行文件的地址, php的配置文件地址, phpExtraPaths 是额外需要代码提示的类库,除了当前项目下的PHP代码可以提示外 phpExtraPaths中定义的目录下的PHP代码也能提示。  D:\SaeServer\php\stdlib 是SaeServer中 SAE本地模拟文件的目录, 所以配置后不管在哪儿 都能有SAE代码的提示。

安装sublimecodeintel后, 按alt+鼠标左键也能和ctags一样跳转到函数声明的地方。 但是如果有两个文件声明了同样名称的函数, sublimecodeintel只会跳转到第一个找到的函数, 而ctags会让你选择要跳转到哪个文件。所以我们一般还是用ctags的跳转功能。

4,语法提示。 我们需要在写代码的时候如果有语法错误,能立即提示我们, 可以安装这两个插件:sublimelint 和Phpcs , sublimeint 需要系统有php命令。 所以需要设置好php的环境变量。 sublimelint的语法错误提示是显示在状态栏上面的,所以在编写程序的时候注意时常看看状态栏。 而Phpcs的语法错误提示是在我们保存文件时弹出万能面板显示错误,sublimelint的错误提示实时但不明显。 Phpcs的错误提示不是实时的,但很明显。 因此我们一般这两个插件都要安装。  Phpcs除了代码提示的共,还有其他功能,但是我暂时没有弄明白其他功能怎么用, 大家可以去研究一下,如果知道怎么用了再告诉我一下。

5,goto document。 这个插件能帮助我们快速查看手册。 比如我们在写php代码时, 突然忘记了某个函数怎么用了,将鼠标放在这个函数上,然后按F1,它能快速打开PHP手册中说明这个函数用法的地方。
安装好 goto document插件后我们再配置快捷键F1 跳转到文档。 打开sublime的菜单栏Preferences->key bindings -User  设置快捷键:

  1. [
  2. { “keys”: [“f1”], “command”: “goto_documentation” }
  3. ]

复制代码

这样设置后, 按F1就能跳转到文档了。

6,function name display。 这个插件可以在状态栏显示出当前光标处于哪个函数中。

7,GBK Encoding Support 。 sublime本身不支持GBK编码, 可以安装这个插件让它支持。

8,SVN插件。windows下可以安装Tortoise和 Tortoisesvn的客户端。然后在sublime中在目录或文件右键都可以提交svn了。 在ubuntu下可以安装rabbitvcs 结合这个插件:https://github.com/kervin/sublime-svn/downloads 实现同样的功能。

9,gist。我们建立html文件时,做有些相同的代码。 这时候我们喜欢能有一个代码模板, 不能写重复相同的代码, gits插件能实现代码模板的功能。 它能见我们自己创建的代码模板,代码片段保持在github中的gist下。http://lucifr.com/2012/03/07/sub … al-snippet-manager/ 这里介绍了详细的用法。

10,代码注释格式化。

additional PHP snippet插件能提示phpdocument格式的代码

还能快速输出开源协议, 输入php- 会有提示

安装DocBlockr 插件,能形成注释块。不用每次敲注释的斜杠或星号。

11,成对匹配的增强。 像这些符号是成对的:花括号{}, 中括号[],括号:() ,引号“” 等。 这些符号当我们鼠标放在开始符号的位置的时候, 希望能明显看到结尾符号在哪儿sublime默认是下划线,很不明显, 想要明显一点,可以安装插件  BracketHighlighter。

12,格式化PHP代码。 安装 php-beautifier 插件,sublime上格式化php的插件找到两个:php tidy和php beautifier,其中php tidy是按照wordpress风格组织代码,不喜欢括号里的那么多空格。。虽然在github上有人改造了一下变成ci风格,但装起来还是比较麻烦的

而php beautifier的安装也同样另人抓狂,但好歹也摸索出来了:

1. 终端下使用pear安装php beautifier ,按照官方说明输入:

1 sudo pear install --alldeps channel://pear.php.net/php_beautifier-0.1.15

2. 在Sublime text中安装beautifier插件,  按ctrl+shift+p 在package control中搜索安装

3. 安装成功后重启Sublime,同样ctrl+shift+p 后输入 Fomat:Php,发现格式化没反应,而且之下弹出警告

4. 搜索系统中beautifier的安装目录 /lib/php/pear/PHP/Beautifier/Filter

打开 Pear.filter.php ,  phpBB.filter.php

注释掉

1 require_once("PEAR/Config.php");

5. 返回Sublime,输入 Format:Php ,格式化成功

13,Xdebug。 可以安装xdebug插件,做代码调试功能。 这是大型IDE都有的功能, 小型编辑器很少能做到,但是sublime却又相应的插件能实现xdebug的功能。

你的PHP需要安装xdebug扩展。使用时需要在项目目录下建立一个.sublime-project文件

  1. {
  2. “folders”:
  3. [
  4. {
  5. “path”: “D:\ysd\ysdv8”
  6. },
  7. ],
  8. “settings”: {
  9. “xdebug”: { “url”: “http://yunshangdian.com” }
  10. }
  11. }

复制代码

path配置项配置了程序所在路径。
注意给程序设置断点。否则不能见效果。 详细用法见:https://github.com/Kindari/SublimeXdebug

你如果也要写前端代码, 还可以安装一些和html,js相关的插件。如 ZenCoding,jQuery,jQuery Mobile Snippets,jQuery Snippets pack等。

二,配置建议。

用户配置建议(打开菜单栏Preferences->Setting-user):

{
“color_scheme”: “Packages/Color Scheme – Default/Monokai.tmTheme”,
“default_line_ending”: “unix”,
“detect_slow_plugins”: false,
“font_face”: “Microsoft YaHei”,
“font_size”: 10.0,
“auto_match_enabled”: false,
}

auto_match_enabled设置为false后可以关闭括号的自动完成。如我们输入左括号时sublime自动将右括号打出来了,往往我们不习惯这样, 此时你设置auto_match_enabled为false即可。

快捷键配置的建议(菜单栏Preferences->key bindings -User):

[
{ “keys”: [“f1”], “command”: “goto_documentation” },
{ “keys”: [“alt+shift+`”], “command”: “clone_file” }
]

F1快速打开文档, 这个快捷键的设置前面已经说了。
alt+shift+` 快捷键又有什么用呢? 我们需要同一个文件在左右两栏同时打开。

先按快捷键: alt+shift+2 。 此时会出现左右两栏的布局。

再按alt+shift+`(`键是tab键上面个键), 此时会复制一份当前文件, 再把新复制的那份文件拖动到右栏。 这样就实现了同一文件左右两栏同时打开了。

切换回一栏布局,按 alt+shift+1

颜色配置建议:

sublime对无效(invalid)的颜色提示 往往会提示错误。颜色很难看。 可以去掉对invalid的颜色提示。
插件目录下\Color Scheme – Default\Monokai.tmTheme文件中, 删除

  1. <dict>
  2. <key>name</key>
  3. <string>Invalid</string>
  4. <key>scope</key>
  5. <string>invalid</string>
  6. <key>settings</key>
  7. <dict>
  8. <key>background</key>
  9. <string>#F92672</string>
  10. <key>fontStyle</key>
  11. <string></string>
  12. <key>foreground</key>
  13. <string>#F8F8F0</string>
  14. </dict>
  15. </dict>

复制代码

成对匹配默认是绿色,有点难看,

插件目录下\Color Scheme – Default\Monokai.tmTheme文件中Class name 键中的:
改为:

  1. <dict>
  2. <key>name</key>
  3. <string>Class name</string>
  4. <key>scope</key>
  5. <string>entity.name.class</string>
  6. <key>settings</key>
  7. <dict>
  8. <key>background</key>
  9. <string>#F92672</string>
  10. <key>fontStyle</key>
  11. <string></string>
  12. <key>foreground</key>
  13. <string>#F8F8F0</string>
  14. </dict>
  15. </dict>

复制代码

三,在linux下使用。

linux下使用时,中文不能输入的问题, 使用scim输入法方式可以解决。具体解决方法:http://www.haogongju.net/art/1312281
虽然scim能让我们输入中文后, 但是也不是很完美,有候选词不跟随的问题, sublime失焦后候选词会消失的问题。候选词消失的问题,可以把sublime独立到一个单独的工作区中来暂时解决这个问题。

Debug

https://github.com/Kindari/SublimeXdebug

Design pattern : Un Singleton PHP

l’article original
Design pattern : Un Singleton PHP
Le design pattern Singleton vous permet, en tant que développeur, de vous assurer qu’une classe n’est instanciée qu’une seule fois durant toute l’exécution de votre script. Ce cas de figure se présente notamment lorsqu’il s’agit de stocker une connexion à une base de données ou de charger un fichier de configuration. Voici un gabarit simple et commenté qui vous permettra de maitriser le concept… pour ceux qui ne le savent pas déjà !

Le concept de base et d’interdire toute instanciation de la classe par ce type de code :

Pour ce faire, nous allons rendre “privé” le constructeur de notre classe (oui, c’est possible), ce qui nous donne quelque chose comme ça :

Très bien. Maintenant, il va quand même falloir l’instancier une (et une seule) fois, cette classe ! C’est la que les méthodes et propriétés statiques viennent à notre secours. Nous allons stocker, dans une propriété statique et privée de notre classe une instance d’elle même, que nous allons distribuer, en l’instanciant si elle est nulle (au premier appel donc). Voici le code :

Le tour est joué ! Pour accéder à l’instance de la classe dans votre code :

参数 和 变量 php

php的引用(就是在变量或者函数、对象等前面加上&符号)

在PHP 中引用的意思是:不同的名字访问同一个变量内容.
与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址

变量的引用

PHP 的引用允许你用两个变量来指向同一个内容

函数的传址调用
传址调用我就不多说了 下面直接给出代码

function test(&$a)
{
$a=$a+100;
}
$b=1;
echo $b;//输出1
test($b); //这里$b传递给函数的其实是$b的变量内容所处的内存地址,通过在函数里改变$a的值就可以改变$b的值了
echo “
“;
echo $b;//输出101

要注意的是,在这里test(1);的话就会出错,原因自己去想

函数的引用返回
先看代码

function &test()
{
static $b=0;//申明一个静态变量
$b=$b+1;
echo $b;
return $b;
}

$a=test();//这条语句会输出$b的值为1
$a=5;
$a=test();//这条语句会输出$b的值为2

$a=&test();//这条语句会输出$b的值为3
$a=5;
$a=test();//这条语句会输出$b的值为6

下面解释下:
通过这种方式$a=test();得到的其实不是函数的引用返回,这跟普通的函数调用没有区别至于原因:这是PHP的规定
PHP规定通过$a=&test(); 方式得到的才是函数的引用返回
至于什么是引用返回呢(PHP手册上说:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。) 这句狗屁话害我半天没看懂

用上面的例子来解释就是
$a=test()方式调用函数,只是将函数的值赋给$a而已,而$a做任何改变都不会影响到函数中的$b
而通过$a=&test()方式调用函数呢, 他的作用是将return $b中的$b变量的内存地址与$a变量的内存地址指向了同一个地方
即产生了相当于这样的效果($a=&b;) 所以改变$a的值也同时改变了$b的值所以在执行了
$a=&test();
$a=5;
以后,$b的值变为了5

这里是为了让大家理解函数的引用返回才使用静态变量的,其实函数的引用返回多用在对象中

对象的引用

abc;//这里输出ABC
echo $c->abc;//这里输出ABC
$b->abc=”DEF”;
echo $c->abc;//这里输出DEF
?>

以上代码是在PHP5中的运行效果
在PHP5中 对象的复制 是通过引用来实现的。上列中$b=new a; $c=$b; 其实等效于$b=new a; $c=&$b;
PHP5中默认就是通过引用来调用对象, 但有时你可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本 . 为了这样的目的,PHP定义了一个特殊的方法,称为__clone.

引用的作用
如果程序比较大,引用同一个对象的变量比较多,并且希望用完该对象后手工清除它,个人建议用 “&” 方式,然后用$var=null的方式清除. 其它时候还是用php5的默认方式吧. 另外, php5中对于大数组的传递,建议用 “&” 方式, 毕竟节省内存空间使用。

取消引用
当你 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。例如:

不会 unset $b,只是 $a。

global 引用
当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的:

这意味着,例如,unset $var 不会 unset 全局变量。

$this
在一个对象的方法中,$this 永远是调用它的对象的引用。

//下面再来个小插曲
php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。

通俗的讲
1:如果有下面的代码

$a=”ABC”;
$b=$a;

其实此时$a与$b都是指向同一内存地址而并不是$a与$b占用不同的内存

2:如果在上面的代码基础上再加上如下代码

$a=”EFG”;

由于$a与$b所指向的内存的数据要重新写一次了,此时Zend核心会自动判断自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储

http://bbs.phpchina.com/viewthread.php?tid=107122