每天一个linux命令(1):ls命令

ls命令是linux下最常用的命令。ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单。 通过ls 命令不仅可以查看linux文件夹包含的文件而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息等等。ls 命令在日常的linux操作中用的很多! 1. 命令格式: ls [选项] [目录名] 2. 命令功能: 列出目标目录中所有的子目录和文件。 3. 常用参数: -a, –all 列出目录下的所有文件,包括以 . 开头的隐含文件 -A 同-a,但不列出“.”(表示当前目录)和“..”(表示当前目录的父目录)。 -c  配合 -lt:根据 ctime 排序及显示 ctime (文件状态最后更改的时间)配合 -l:显示 ctime 但根据名称排序否则:根据 ctime 排序 -C 每栏由上至下列出项目 –color[=WHEN] 控制是否使用色彩分辨文件。WHEN 可以是’never’、’always’或’auto’其中之一 -d, –directory 将目录象文件一样显示,而不是显示其下的文件。 -D, –dired 产生适合 Emacs 的 dired 模式使用的结果 -f 对输出的文件不进行排序,-aU 选项生效,-lst 选项失效 -g 类似 -l,但不列出所有者 -G, –no-group 不列出任何有关组的信息 -h, –human-readable 以容易理解的格式列出文件大小 (例如 1K 234M 2G) –si 类似 -h,但文件大小取 1000 的次方而不是 1024 -H, –dereference-command-line 使用命令列中的符号链接指示的真正目的地 –indicator-style=方式 指定在每个项目名称后加上指示符号<方式>:none (默认),classify (-F),file-type (-p) -i, –inode 印出每个文件的 inode 号 -I, –ignore=样式 不印出任何符合 shell 万用字符<样式>的项目 -k 即 –block-size=1K,以 k 字节的形式表示文件的大小。 -l 除了文件名之外,还将文件的权限、所有者、文件大小等信息详细列出来。 -L, –dereference 当显示符号链接的文件信息时,显示符号链接所指示的对象而并非符号链接本身的信息 -m 所有项目以逗号分隔,并填满整行行宽 -o 类似 -l,显示文件的除组信息外的详细信息。 -r, –reverse 依相反次序排列 -R, –recursive 同时列出所有子目录层 -s, –size 以块大小为单位列出所有文件的大小 -S 根据文件大小排序 –sort=WORD 以下是可选用的 WORD 和它们代表的相应选项: extension -X status -c none -U time -t size -S atime -u time -t access -u version -v use -u -t 以文件修改时间排序 -u 配合 -lt:显示访问时间而且依访问时间排序 配合 -l:显示访问时间但根据名称排序 否则:根据访问时间排序 -U 不进行排序;依文件系统原有的次序列出项目 -v 根据版本进行排序 -w, –width=COLS 自行指定屏幕宽度而不使用目前的数值 -x 逐行列出项目而不是逐栏列出 -X 根据扩展名排序 -1 每行只列出一个文件 –help 显示此帮助信息并离开 –version 显示版本信息并离开 4. 常用范例: 例一:列出/home/peidachang文件夹下的所有文件和目录的详细资料 命令:ls -l -R /home/peidachang 在使用 ls 命令时要注意命令的格式:在命令提示符后,首先是命令的关键字,接下来是命令参数,在命令参数之前要有一短横线“-”,所有的命令参数都有特定的作用,自己可以根据需要选用一个或者多个参数,在命令参数的后面是命令的操作对象。在以上这条命令“ ls -l -R /home/peidachang”中,“ls” 是命令关键字,“-l -R”是参数,“ /home/peidachang”是命令的操作对象。在这条命令中,使用到了两个参数,分别为“l”和“R”,当然,你也可以把他们放在一起使用,如下所示: 命令:ls -lR /home/peidachang 这种形式和上面的命令形式执行的结果是完全一样的。另外,如果命令的操作对象位于当前目录中,可以直接对操作对象进行操作;如果不在当前目录则需要给出操作对象的完整路径,例如上面的例子中,我的当前文件夹是peidachang文件夹,我想对home文件夹下的peidachang文件进行操作,我可以直接输入 ls -lR peidachang,也可以用 ls -lR /home/peidachang。 […]

解决Ubuntu更新nVidia显卡驱动后黑屏问题

跟大数据没关系,自己使用的一个记录。 现在已经完全抛弃windows了,完全用ubuntu来干活了。不是windows不好,是中国的windows生态环境太差了,随便装个国产小软件会附带给用户装一堆垃圾的东西,什么各种毒霸,各种手机助手,各种输入法,稍微点错个什么按钮就装一堆的垃圾,到处都是陷阱,就连开源的SourceForge推出的FileZilla安装器,后台还偷偷自动下载Norton 360强制安装。他妈的老外都被中国这帮臭流氓软件公司带坏了。用户还根本没得选择,所以干脆痛下决心,把Windows干掉,直接上ubuntu了,使用方法习惯了几天就好了,把eclipse也换成了IntelliJIDEA,感觉开发效率比用windows的时候还高不少,现在再看别人用windows觉得那玩意就是渣渣啊。除了网银还得虚拟机,别的真的没啥需要windows来做的。而且,说实话,在linux下用命令行解决问题比用界面解决快多了。 但是,又说但是了,Linux系统虽然很好,可显卡厂商对它支持并不好,我用了半年ubuntu,基本出问题都是在nVidia显卡上,Linus Torvalds曾经在大会上当众对英伟达竖中指,并说”Fuck you nVidia”。我的使用的感觉也是一样的。 官方linux版本驱动更新太慢,ppa的bumble bee里面有最新的驱动,但是不稳定。昨晚上就被搞黑屏了。笔记本是intel/nVidia双显卡,平时都是用intel集显,没啥大问题,昨晚下载安装了xorg-edgers的349驱动,然后选了一下nVidia显卡,结果直接启动黑屏了,怎么折腾都不行。Google被屏蔽,百度上翻好几页基本都是建议重装系统,所以再次吐槽百度,搜索正经事出来的结果就是垃圾。特别提醒程序员们,如果想提高自己的各种水平,花钱买VPN翻墙上google也不能用百度,用百度的程序员处于鄙视链的最底层,是程序员里的败类,不管你用什么语言。:) 然后还是翻墙上了谷歌,第一条就搜到想要的答案了。很快就解决了,适用于nVidia更新非官方显卡驱动后启动黑屏或花屏,整理方法如下,记录一下,省的以后忘了。 启动黑屏后可以按Ctrl-Alt-F1进入命令行界面。这个是基础知识,需连网。 进入cli模式后,sudo apt-get install ppa-purge sudo ppa-purge xorg-edgers sudo apt-get purge nvidia-* 创建一个临时文件夹如 mkdir ~/tmp cp /etc/X11/xorg.conf* ~/tmp sudo apt-get autoremove sudo apt-get update sudo apt-get upgrade sudo reboot 重启后还是C+A+F1进命令行 sudo apt-get install nvidia-331 nvidia-prime sudo cp ~/tmp/xorg.conf.nvidia-xconfig-original /etc/X11/xorg.conf sudo vi /etc/X11/xorg.conf 确保内容如下 Section “ServerLayout” […]

你为什么那么怕鬼?

图片来自网络 本文来自壹读微信【壹读百科】栏目 壹读微信号:yiduiread 清明节假期过了,生活步入正轨。清明节也算在中国三大鬼节之一,虽然这个节日一点也不恐怖,可能是因为……有假放,咳咳。 但总的来说,对于鬼,大部分人是畏惧的。但是怕鬼的同时,问一句,你信鬼吗?得到的答案不一定是一个坚定不移的“信!”。 怕鬼是一种令人矛盾的情绪,当你正儿八经地想这个问题的时候,想出来的结果可能是:这玩意儿没什么可怕的。壹读君(yiduiread)也有理由相信,鬼应该是害怕被壹读君附身的,而不是反过来。但很多人就是控制不住在看鬼片的时候拉人壮胆,或者听到奇怪的声音陷进无穷的联想……今天,壹读君就来帮你理理清,人为什么那么怕鬼? 宋定伯附体的实习壹读君︱陈娣 因为“鬼”长得丑 所谓“长的丑不是你的错,但出来吓人就是你不对了”。没错,根据日本机器人专家森政弘的观点,你怕鬼是因为他们长的太丑了。 单从外形上讲,鬼怪就是一种仿人类形象,但要仿得恰到好处让人喜欢可不简单。一个形象越接近于人类,我们就会越喜欢他,然而当这种接近达到70%左右时,我们的好感就会突然逆转为负值,随着相似度的进一步增加,我们就又开始慢慢喜欢了,这就是“恐怖谷”理论。 想想一个身穿白裙的小女孩,一个人蹲在小巷尽头,路灯光线很暗,你慢慢走近,发现她湿漉漉的头发滴湿了一地,你拍拍她的肩,她缓慢呆滞地抬起头,向你投来凄厉的眼神……这时候你就该打冷颤了。你以为这是个孩子,可是她的表现却不像个孩子,虽然你不一定立马联想到鬼,但也会禁不住起一身鸡皮疙瘩。这就是一种类似于认知失调的反应。也就是说,当仿人类形象的外表和动作接近于人类、又不完美拟合时,观察者就会产生反感心理。而鬼魂、僵尸、假肢正是让人好感度降到谷底的形象。 壹读君(yiduiread)由此猜想,或许东施效颦也是这个道理,模仿不像反而让我们反感,所幸还只是让人反感还没觉得恐怖。 你天生就信肉体可死,灵魂不灭 可你还是不明白,离开荧幕后,为什么你还会把这种恐惧心理衍伸到现实生活中,以至于不敢关灯睡觉呢? 摸摸头,壹读君(yiduiread)告诉你:怕鬼其实是你的本能。 美国阿肯色大学的心理学家杰西•贝林让4到12岁的孩子看了一出木偶剧:一只迷路的小老鼠,又饿又困,被一条鳄鱼发现,残忍地吃掉了。接着,杰西•贝林问了孩子们一些问题,比如饥饿的小老鼠还需要吃东西吗?大脑还工作吗?小老鼠还爱它妈妈吗? 这让杰西•贝林觉得,把生理和心理分开的身心二元论似乎是一种本能,是大脑默认的认知系统,相反,认识到人死后不再有心理功能才是后天习得的。也就是说,人在本能上是相信有鬼的。 杰西•贝林的观点得到耶鲁大学心理学家鲍尔•布鲁姆的支持,他认为正是这种分离的认知系统为我们的超自然信仰提供了基础。 然而,按照杰西•贝林的观点,我们应该会随着后天习得的认识的增长对鬼怪建立一套免疫系统;所以,这并不能解释为什么不相信有鬼阻止不了你怕鬼。 鬼宅心慌慌?有可能是次声波在调戏你 这就不能全怪你了,因为“鬼魅作祟”是存在的,电气工程师维克•坦迪就曾在实验室亲眼看见一把花剑中邪似的在地板上疯狂抖动。难道这就是传说中的鬼上身? 让壹读君(yiduiread)告诉你吧,这其实是次声波搞的鬼。坦迪眼中的花剑也是在排气扇产生的次声波作用下开始“鬼上身”。 碰到如此异样又莫名其妙的事情,除了一个“鬼”字,你还能作何解释?借助次声波,英国一位淘气的传播心理学家理查德•怀斯曼和声学家萨拉•安格列斯让人们集体撞了次鬼。他们把次声波混入音乐旋律,通过下水管道释放出来,让音乐会现场200名观众中的22%以为自己撞鬼了。想想听现场音乐听出撞鬼的感觉,也真是醉了。 不过根据坦迪的研究,这种次声波存在于很多建筑物中,强风吹进窗户,街道上嘈杂的交通,都会产生次声波。他也曾到各地一些传言闹鬼的地下室、城堡、教堂等进行检测,果然在门道、走廊等处检出比较强的次声波——这或许能帮一些鬼宅洗白。 其实,鬼,你值得拥有 不过,千万别想着把责任推干净。想想在同样的环境下,为什么你怕得要死别人却一点儿事都没有?不是你胆子小,只怪你想象力丰富又容易被催眠。 关着门的衣橱、虚掩的木门、月光下生锈的铁窗、雨夜里忽闪忽闪的路灯……这本来都是日常生活中的场景,但放到想象力丰富的人面前,就变成鬼出场的前奏了。理查德•怀斯曼发现次声波、丰富的想象力和容易被催眠是撞鬼的三大要素。 想象力越丰富、越容易被催眠的人也越能成功地说服自己——哦,我感觉到了,他就在后面,就在右肩边上,他在靠近我,他的手就要抓住我了,完了,抓住我了,好冷,我走不动了,我的脚被定住了,完了我动不了…… 可是,如果你告诉壹读君(yiduiread),即使明白了这些道理,你还是免不了听到天花板上的弹珠声就想起《催眠大师》里面的孙婆婆甚至不敢往床底下看,那壹读君就只能理解为,你很甘心做鬼下臣了——亲爱的,你需要鬼。 不要以为壹读君(yiduiread)在冤枉你,有84%的人都是你的同类哦。所谓“人在吃,称在看”,哦,不对,“人在做,天在看”,人类在社会层面是需要怕鬼的。杰西•贝林发现,即使是不相信有鬼的人,被告知正处于有鬼出没的地方时,行为都会更规范。 有一种观点认为,这是人类进化而来的本能。鬼的存在建立了一种类似于全景监狱的监视系统,能在无形中规范人的行为,增加人的亲社会行为,从而帮助人们在集体中存活下来。从这个角度讲,鬼和宗教有了同等的意义。 此外,实验还证明,我们倾向于把世间万物当做是设计好的、有目的、有联系的,比如,我们常常会从一些随机的自然现象中寻找因果关系,看成是上天的某种启迪——很多人前一天晚上梦见飞机失事,第二天就临时决定改换航班。 所以说,下次再有怕鬼的情绪,不妨想想是你需要这个玩伴呢……祝你今晚好眠!

谨记六大定律

1.摆阔定律:越穷的人越爱摆阔。 2.担心定律:越担心的事越容易发生。 3.般配定律:靓男倩女多与自己外表相反的厮守终身。 4.要求定律:越说随便和怎么都行的人要求越高。 5.沟通定律:世上70%的烦恼由沟通不畅所致。 6.装病定律:你之前装了什么病,之后就会容易得什么病。

js中判断json是否为空

var jsonStr ={}; 1、判断json是否为空 jQuery.isEmptyObject(); 2、判断对象是否为空: 1、if (typeOf(x) == “undefined”) 2、if (typeOf(x) != “object”) 3、if(!x) 其中第三种是最简单的方法,但是第三种就不能用if(x)这种互斥的方法去判断,只能在对象前面加! 3、json的key是不可以重复的; jsonStr[key]=”xxx”,存在在替换,不存在则新增。 4、遍历json for(var key in jsonStr){ alert(key+” “+jsonStr[key]) } js如何判断一个对象{}是否为空对象,没有任何属性 前段时间用js写了一个类似”angularjs”用于数据绑定的东西,功能是比较简单了, 通常应该传进来的是一个ArrayList JSON对象数组, 但有时候通过AJAX方法调用返回的是一个JSON对象,而不是数组! 为了兼容这种情况使用了以下代码: [javascript] view plaincopy在CODE上查看代码片派生到我的代码片 if (typeof model.rows === “object” && !(model.rows instanceof Array)){ model.rows = [model.rows]; } 这段代码在后来使用过程中发现了一个Bug,就是当 [javascript] view plaincopy在CODE上查看代码片派生到我的代码片 model.rows = {}; […]

PHP里 switch case条件语句的问题

<?php $a = “abc”; switch ($a) { case 0:echo “a 为 0”;break; case “cdaf”:echo “a 为 cdaf”;break; case “abc”: echo “a 为 abc”;break; default:echo “a 什么都不是”;break; } ?> 运行这段代码为什么输出的结果是‘a为0’ 而不是‘a为abc’?这个0有什么玄机呢? 这个问题应该从PHP作为动态脚本语言说起:动态语言的变量类型是随存储的变量而变化的,即变量类型是根据具体环境而进行变化的。字符串”abc”,指确切字符串,但是对于PHP存储的时候它是不能确定的,因为随着语义的变化,其所起的作用也会变化第一个 case 0:, PHP脚本将常量0翻译为确切的整数,与字符串比较大小时,需要将字符串转换为整数。PHP脚本会将字符串abc,从十进制(默认)转换为数字,但是abc很明显不能代表十进制数,即转换失败,则PHP将结果置为0,如果将字符串表示为”0xabc”,那么PHP脚本能够发现0x标识,将abc作为十六进制转换,所以能够得到abc标识的十六进制整数。从C语言可以做一个简单比较:C中的case必须是数字常量,而不能是字符串,就因为C是变量类型确定的,运行时不能将确定的变量按语义随意转换。而PHP可以,因为PHP语言是动态的,变量类型是动态的。或者从PHP的例子中学习:如果一个文件将111111字符串(不是数字)存储到文件,然后从文件直接读取到变量$a,如下语法就可以将$a作为整数计算: 0+$a 上述表达式得到的结果也可以作为动态语言的一个变现来看

SQLSERVER建立索引 注意的问题

人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的 性能差异,这种性能差异在大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS)中表现得尤为明 显。笔者在工作实践中发现,不良的SQL往往来自于不恰当的索引设计、不充份的连接条件和不可优化的where子句。在对 它们进行适当的优化后,其运行速度有了明显地提高!下面我将从这三个方面分别进行总结: —- 为了更直观地说明问题,所有实例中的SQL运行时间均经过测试,不超过1秒的均表示为(< 1秒)。 —- 测试环境– —- 主机:HP LH II —- 主频:330MHZ —- 内存:128兆 —- 操作系统:Operserver5.0.4 —-数据库:Sybase11.0.3 一、不合理的索引设计 —-例:表record有620000行,试看在不同的索引下,下面几个 SQL的运行情况: —- 1.在date上建有一个非群集索引 select count(*) from record where date >’19991201′ and date < ‘19991214’and amount >2000 (25秒) select date,sum(amount) from record group by date(55秒) select count(*) from record where date >’19990901′ and place in (‘BJ’,’SH’) (27秒) —- 分析: —-date上有大量的重复值,在非群集索引下,数据在物理上随机存放在数据页上,在范围查找时,必须执行一次表扫描才能找到这一范围内的全部行。 —- 2.在date上的一个群集索引 select count(*) from record where date >’19991201′ and date < ‘19991214’ and amount >2000(14秒) select date,sum(amount) from record group by date(28秒) select count(*) from record where date >’19990901′ and place in (‘BJ’,’SH’)(14秒) —- 分析: —- 在群集索引下,数据在物理上按顺序在数据页上,重复值也排列在一起,因而在范围查找时,可以先找到这个范围的起末点,且只在这个范围内扫描数据页,避免了大范围扫描,提高了查询速度。 —- 3.在place,date,amount上的组合索引 select count(*) from record where date >’19991201′ and date < ‘19991214’ and amount >2000(26秒) select date,sum(amount) from record group by date(27秒) select count(*) from record where date >’19990901′ and place in (‘BJ, ‘SH’)(< 1秒) —- 分析: —- 这是一个不很合理的组合索引,因为它的前导列是place,第一和第二条SQL没有引用place,因此也没有利用上索引;第三个SQL使用了place,且引用的所有列都包含在组合索引中,形成了索引覆盖,所以它的速度是非常快的。 —- 4.在date,place,amount上的组合索引 select count(*) from record where date >’19991201′ and date < ‘19991214’ and amount >2000(< 1秒) select date,sum(amount) from record group by date(11秒) select count(*) from record where date >’19990901′ and place in (‘BJ’,’SH’)(< 1秒) —- 分析: —- 这是一个合理的组合索引。它将date作为前导列,使每个SQL都可以利用索引,并且在第一和第三个SQL中形成了索引覆盖,因而性能达到了最优。 —- 5.总结: —- 缺省情况下建立的索引是非群集索引,但有时它并不是最佳的;合理的索引设计要建立在对各种查询的分析和预测 上。一般来说: —- ①.有大量重复值、且经常有范围查询 (between, >,< ,>=,< =)和order by 、group by发生的列,可考虑建立群集索引; —- ②.经常同时存取多列,且每列都含有重复值可考虑建立组合索引; —- ③.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。 二、不充份的连接条件: —- 例:表card有7896行,在card_no上有一个非聚集索引,表account有191122行,在 account_no上有一个非聚集索引,试看在不同的表连接条件下,两个SQL的执行情况: select sum(a.amount) from account a,card b where a.card_no = b.card_no(20秒) —- 将SQL改为: select sum(a.amount) from account a,card b where a.card_no = b.card_no and a.account_no=b.account_no(< 1秒) —- 分析: —- 在第一个连接条件下,最佳查询方案是将account作外层表,card作内层表,利用card上的索引,其I/O次数可由以下公式估算为: —- 外层表account上的22541页+(外层表account的191122行*内层表card上对应外层表第一行所要查找的3页)=595907次I/O —- 在第二个连接条件下,最佳查询方案是将card作外层表,account作内层表,利用account上的索引,其I/O次数可由以下公式估算为: —- 外层表card上的1944页+(外层表card的7896行*内层表account上对应外层表每一行所要查找的4页)= 33528次I/O […]

SQL数据库查询语句/连接查询/多表连接查询

一、 简单查询 简单的Transact-SQL查询只包括选择列表、FROM子句和Where子句。它们分别说明所查询列、查询的表或视图、以及搜索条件等。 例如,下面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。 Select nickname,email FROM testtable Where name=’张三’ (一) 选择列表 选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变量和全局变量)等构成。 1、选择所有列 例如,下面语句显示testtable表中所有列的数据: Select * FROM testtable   2、选择部分列并指定它们的显示次序 查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。例如: Select nickname,email FROM testtable   3、更改列标题 在选择列表中,可重新指定列标题。定义格式为: 列标题=列名 列名 列标题 如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列标题: Select 昵称=nickname,电子邮件=email FROM testtable 4、删除重复行 Select语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重复的数据行,默认为ALL。使用DISTINCT选项时,对于所有重复的数据行在Select返回的结果集合中只保留一行。 5、限制返回的行数 使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是表示一百分数,指定返回的行数等于总行数的百分之几。例如: Select TOP 2 *FROM testtable Select TOP 20 PERCENT * FROM testtable   (二) FROM子句 FROM子句指定Select语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,它们之间用逗号分隔。 在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应使用下面语句格式加以限定: Select username,citytable.cityid FROM usertable,citytable Where usertable.cityid=citytable.cityid   在FROM子句中可用以下两种格式为表或视图指定别名: 表名 as 别名 表名 别名 例如上面语句可用表的别名格式表示为: Select username,b.cityid FROM usertable a,citytable b Where a.cityid=b.cityid   Select不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查询数据。例如: Select a.au_fname+a.au_lname FROM authors a,titleauthor ta (Select title_id,title FROM titles Where ytd_sales>10000 ) AS t Where a.au_id=ta.au_id AND ta.title_id=t.title_id […]

CI加载流程及结构分析(一)

入口文件入口文件主要完成下列工作: 1. 指定 CodeIgniter 框架所在目录; 2. 定义 APPPATH 常量,指示应用程序文件根目录; 3. 载入 codeigniter/CodeIgniter.php 文件,启动框架。 codeigniter/CodeIgniter.php 文件这个文件是 CodeIgniter 的基本文件,主要完成初始化 CodeIgniter 框架和启动应用程序两项工作。 1. 实例化 CI_Benchmark,这个类用于标记应用程序执行消耗的时间; 2. 载入应用程序的配置文件 require(APPPATH.?config/config&#8216;.EXT); 3. 实例化 CI_Config,这个类用于将数组封装为可以操作的配置服务; 4. 实例化 CI_Router,这个类用于分析 URL 请求,确定要执行的控制器和动作; 5. 实例化 CI_Output,这个类提供输出内容的缓存和检查服务; 6. 通过 $OUT->_display_cache($CFG, $RTR) 尝试输出缓存内容,如果成功,则结束程序运行; 7. 判断控制器类定义文件是否存在。如果不存在则通过 show_404() 显示错误信息; 8. 实例化 CI_Input,这个类提供对 $_GET、$_POST 的访问手段,并封装了一些过滤方法; 9. 实例化 CI_URI,这个类提供对 URL 的分析、构造服务; 10. 实例化 CI_Language,这个类提供多语言字符串映射服务; 11. 载入 codeigniter/Base4.php 或者 codeigniter/Base5.php; 12. 载入 libraries/Controller.php; 13. 载入控制器类定义文件; 14. 实例化控制器类; 15. 如果控制器使用了 scaffolding 功能,则调用控制器的 _ci_scaffolding() 方法,否则调用控制器动作方法; 16. 通过 $OUT->_display(); 输出内容($OUT 是 CI_Output 的实例)。 CI_Benchmark 这个类很简单,就是用 microtime() 函数记录时间点,并提供 elapsed_time() 方法来计算两个时间点之间消耗的时间。这个类功能不多,但是很实用。CodeIgniter 中大部分类都是这种设计思想,值得称赞! CI_Config 这个类其实是在内部维护了一个数组,用来记录应用程序的设置(类似 Windows 注册表)。这种简单的封装可以强制应用程序按照固定的规范访问设置,同时又不将设置保存为全局变量,避免无意中遭到破坏或篡改。 CI_Router CI_Router 功能很单一。CI_Router 首先分析出应用程序当前使用的 URL 模式:PATHINFO 或普通模式。接下来从 URL 地址中分析出控制器名字、动作名以及参数名和参数值。分析的结果保存为 CI_Router 对象实例的成员变量。这里比较有特点的是,CI_Router 可以根据开发者在应用程序设置里面定义的模式来分析 URL,而不是使用某种固定的模式。 CI_Output CI_Output 有两个主要功能:获得应用程序执行的所有输出内容和输出缓存服务。应用程序执行的输出结果都会保存为 CI_Output 的成员变量。然后根据应用程序设置,CI_Output::_display() 方法会调用 CI_Output::_write_cache() 方法将输出内容缓存起来。下一次当使用 CI_Output::_display_cache() 时如果缓存已经建立了,并且没有过期,则会直接输出缓存内容。在 CI_Output::_write_cache() 中,是根据 URL 地址和 URL 参数来确定缓存 ID 的。因此即便是同一个控制器和动作,只要使用不同的 URL 参数,也会缓存不同的内容。这个类的功能很简单,因此在许多动态页面是无法使用的。例如用户登录前和登录后,访问同一个控制器和动作并使用相同的 URL 参数,页面内容也有可能是不同的。这时,CI_Output 的缓存就不能使用。因为从本质上来说,CI_Output 提供的缓存是在应用程序之外的,所以应用程序无法根据当前状态来决定是否缓存页面。当一个页面被缓存后,对该页面的访问实际上根本就不会执行应用程序代 码,而是由 CI_Output 取出缓存内容直接就输出了。 CI_Input CI_Input 是输入数据过滤器,并且提供了对 $_GET、$_POST 的封装服务。例如用 CI_Input::post() 方法来访问 $_POST。由于多了这层封装,CI_Input 可以在 post() 方法中对数据进行更多的过滤。这种封装从出发点上看,是很不错的。但是这也会造成一些问题。例如 CI_Input 只有在调用 post() 方法时才能进行过滤。如果应用程序使用 $_POST 直接获取数据,那么实际上就绕过了安全屏障。如果应用程序使用了第三方库,那么这种风险更大,因为第三方库很可能会直接使用 $_POST 等全局变量。因此有些开发者认为过滤应该是全局的,即在框架初始化时,就对所有输入数据进行过滤。但初始化时的全局过滤灵活性很差,要么全过滤,要么都不 过滤,没法做到对个别数据的单独过滤。 CI_Input 的另一个问题,就是没有处理 magic_quotes。不管 magic_quotes 设置为什么,CI_Input 都没有对数据进行相关的处理。这样一来,如果服务器的 magic_quotes 设置不同,那么应用程序得到的数据也是不一致的。后来查看数据库驱动的代码,发现 CI_Input 将对 magic_quotes 的处理放到了数据库驱动中。这种设计是有很大缺陷的!如果应用程序取得数据后,并不是存入数据库(例如直接显示或存入文件),那么就必须自行判断 magic_quotes 的状态。这种判断不但烦琐,而且容易遗忘。所以框架有责任将所有数据整理为一致的格式,要么是应用 addslashes() 转义过后的数据,要么是没有转义的数据。奇怪的是 CI_Input 却对输入数据的字段名进行了 magic_quotes 检查,并应用了 addslashes()。这是为了让数据库字段名不会成为 SQL 注入攻击的根源。甚至,CI_Input 还会将 \n\r\n\r 替换为 \n。这种随意篡改原始数据的做法,非常不可取。总之,我个人认为 CodeIgniter 在这部分的设计是很糟糕的。不过要改善也很简单,几行代码就可以了。然后修改一下数据库驱动。但是由于已经有许多采用 CodeIgniter 开发的应用程序,所以这样的升级改动,影响是非常大的。 CI_URI 由于 CodeIgniter 允许应用程序定义 URL 映射模式,所以需要专门的工具来生成 URL 地址。CI_URI 就是完成这些工作的。 […]

Codeigniter调用PHPExcel 导入excel例子

1.把PHPExcel放到application\libraries下,并新建个tool.php用来调用 PHPExcel官方网站: http://www.codeplex.com/PHPExcel <?php class Tool{ /**导入Excel文件到MySql数据库 $file:Excel文件的名称; $filetempname:Excel文件上传到服务器的临时文件名 $sql:传入的sql语句 **/ function UploadExcel($file,$filetempname,$strsql) { set_include_path(get_include_path().PATH_SEPARATOR .BASEPATH.’libraries/PHPExcel/PHPExcel’); require_once ‘PHPExcel/PHPExcel.php’; require_once ‘PHPExcel/PHPExcel/IOFactory.php’; require_once ‘PHPExcel/PHPExcel/Reader\Excel5.php’; $tools_filePath = dirname(dirname(dirname(dirname(__FILE__)))).”/UploadFiles/”; $tools_filePath = str_replace(‘\\’,’/’,$tools_filePath); //防止最大可使用的内存总量过少 if(intval(ini_get(‘memory_limit’)) <= 20) { ini_set(‘memory_limit’,’20M’); } $uploadDir = $tools_filePath; if (!is_dir($uploadDir)) { if (!mkdir($uploadDir, 0777,TRUE) || !chmod($uploadDir, 0777)) { exit(“创建上传目录失败”); } } $filename = explode(“.”,$file);//把上传的文件名以“.”好为准做一个数组。 $date […]