URL_PATHINFO_DEPR, depr表示 网页路径"分隔符",用"-", 有利于seo,注意是从 sername/index.php(开始的)/home-user-login-var-value开始的,pathinfo也支持普通的参数传值(仅仅支持参数...). 在thinkphp中,有两个地方使用depr,另一个就是tpl的文件目录组织分隔符: 'TMPL_FILE_DEPR'=>'-'
URL_PATHINFO: 意思是路径信息,意思是 网页的url地址就表明了 网页的模块/控制器/操作等信息, 即path indicates info of the page.
'TAGLIB_BEGIN' => '<' 如果修改为[, 则扩展标签(也叫xml标签)的调用就是 [volist....]... [/volist], xml标签定界符 不能跟基本标签符号如{,相冲突...否则会引起解析错误.
如何生成tp3.2.3的多个模块?
- 可以用手动创建类似Home模块的Admin模块目录
- 用
define('BIND_MODULE' => 'Admin');
将index.php入口文件绑定到Admin模块,由于Admin模块不存在,所以第一次访问localhost时会自动创建 Admin模块的目录. - 以后要注释掉 BIND_MODULE 模块, 恢复默认的入口为Home模块..., 以后使用Admin模块就如同Home模块一样的方法使用了...
标签库的配置,TAGLIB_PRE_LOAD => "cx,custom"
和TAGLIB_BUILT_IN=>"cx,custom"
是两个不同的配置,前者主要是 用于外在的 自定义的 自己创建的标签库在tp启动时就载入,适用于外在标签在多个模板大量使用的场合,不必在 模板页面再用<taglib name="custom"> 注意,所有的标签都是小写的
载入;后者是指在使用标签时不必在前面加上标签库名称,如<custom:great name="uid" value="1">...</custom:great>, 如果定义了custom为内置标签,则直接写<great name="uid" value="1">....</great>
在tp中,在模板html文件中,凡是可以使用普通变量如 {$name} 的地方,都可以使用系统变量,{$_Get["name"]},{$Think.config.name},而且可以使用函数...
在xml标签中,注意区分 "变量" 和 "变量名称"的区别, 变量是要加$,而变量名称 则不加$. 通常像 <volist name="user" id="vo">....</volist>
中的name属性使用的是变量名称, 在value属性中要使用变量,则要加上$. 同时在标签外面的,纯粹的普通变量的输出要加$: {$name}
volist和foreach?
volist 中的vo可以认为是, vector output,(数组/矢量输出) 也可以认为是数组/矢量 对象vector object. volist就是矢量对象列表. volist主要是用于数据表查询结果或二维数组的输出, foreach主要用于对象或数组的输出. volist的属性主要有name, id, offset-length(用于部分输出),mod. 而foreach的属性有name,item ,key
volist的mod?
它是一个属性,也可以认为是一个赋值, <volist ... mod="2,5,x"> 等价于 <volist name="result" id="vo" key="i"> ...<assign name="mod" value="$i mod x"> mod="2" 实际上是 mod="key % 2"
但是你不能单独的去赋值mod, 要在volist循环中赋值,所以就直接 写在volist的属性中了, 通常要把olist mod="x" 和 eq name="mod" value="1""2""..." 结合起来使用.
通常写volist的 id就直接写成 vo, 这是约定 习惯:<volist name="result" id="vo">
对tp标签库的理解,不管有多复杂, 就是把它理解为 解释扩展的 <?php .... ?>
代码. 解析后的代码实际上是一个 php和html混合的页面. 扩展的xml标签是为了在 html中不只是 "肯定的,不变的"输出 模板变量, 而且还要实现如同 php/js等代码程序中的 条件语句if, switch, 和循环语句for foreach volist等, 用"纯粹的html标签式的页面" 来代替html和php的混合页面.
compare标签和eq等标签, range标签和between等标签?
eq, gt等比较标签,是compare标签的别名, 都有name, value属性,只是compare标签多了一个type属性来指明是eq, gt,lt(less than)等.注意, 比较标签和范围标签其实都是 条件标签 if,都要解析为if条件语句... 只是比if标签更简洁.
tp中的模板标签和 html标签 的用法不同!! html标签是不允许 在标签名 中 嵌套的, 如:<p <span> span text</span>> para text </p>
的写法是错误的, 但是tp中的 模板标签, 由于要解析成php代码, 所以 在 一个标签的名称中, 在标签的属性中, 是可以"嵌套" 其他tp标签的, 如: <tr <eq id="uid" value="1">style="background-color:#eee"</eq>> ....<td>....</td> </tr>
php中的empty和isset的区别?
empty是判断是否为空,而isset是判断该变量或数组的元素是否设置,
通常, 如果 $var=0,false,null,'', 则empty($var)====true
对于isseet来说, 跟上面的一样,当 $var=0,false,''时, 则isset($var)=true,只有一个, 当$var=null的时候, isset($var)===false.
数组和对象的写法区别? 数组的写法是 $arr['key'], 对象的写法则是用冒号表示: $obj:member, 而要自动识别时,则用点号 $some.member, 但是,在能够确定时,最好是写明确些
import和vendor函数的区别?
它们其实都是在内部调用的 require, 只是开始的部分做了些调整, 如果是ThinkPHP下的 Library/Think(或者core)下的类都是可以直接使用 , 如果是 Library下的Org,则用import来引入类, 如果是Vendor下的类,要引入, 则用vendor函数, 他们的区别, 只是针对的路径不同.
通常自己写的类/类库,或引入的 按tp的规则 写的其他人,开发团队写的 类库, 都放在 Org目录下, 使用import来引入; 如同在C++中一样,如果是没有按tp默认约定规则来写的\放在vendor目录下的类库, 就用vendor方法来引用, 只是import和vendor的参数的默认值不同.
tp的show,display,直接echo的区别?
echo就是直接输出内容,跟tp函数没有毛关系; display和show都是View类的成员函数, 都有三个参数('tmpl对应文件','charset,doc-type),但是display要求要有对应的tmpl文件, 而show则不一定要有对应的tmpl文件, 可以直接输出html内容...
php是解释型语言, 解释一句,再执行一句,所以前面有输出,当后面有错误时,会终止运行,只是并不是直接翻译成机器码: 先将php源代码转换为opcode(如同在汇编语言中,nop是助记符, 0x90是opcode...,即计算机的中间代码),然后由php的解释引擎(php虚拟机,pvm): zend 来运行,也可以用jit技术在虚拟机上运行时编译成机器码来提高运行速度. 现在的语言,编译和解释的分别都不是那么严密了.
使用高版本的php, 功能更强大,
像__ROOT__, PUBLIC,...等都是在模板文件中,使用的, 不是在 控制器/方法|操作,中使用的, 而且是在 配置文件中的 TMPL_PARSE_STR' => array( '__PUBLIC' => ...,.....)
中定义的, 因为在默认情况下, ROOT, PUBLIC__这些都是要被解析\替换的,所以如果确实要输出 像__ROOT, __PUBLIC__这样的字符串, 则可以使用 另外的模板字符串定义 TMPL_PARSE_STR' => array( '--PUBLIC--' => '__PUBLIC__' ...,.....)
ThinkPHP的内置标签库在哪里?
内置标签库的基类是: \ThinkPHP\Library\Think\Template\TagLib.class.php, 内置的标签库cx(标签库的名称都用小写)在\ThinkPHP\Library\Think\Template\TagLib\Cx.class.php文件中.
C/C++为什么要使用指针分配对象?
Object myobj这种方式是自动分配,作用域在函数范围内,当1. (使用指针会带来两个作用,也可以说是 两个问题,看你是需要还是避免) 要延长对象的作用域和生命期, 并且要使用的是对象指向内存的本身, 而不是对象的拷贝; 2.要指向的对象本身分配的内存比较大,如果用对象的拷贝,耗费的内存比较大,可能溢出栈 时, 使用只能指针比较好, 具有RAII std::unique_ptr, std::shared_ptr, ...(这个比较少见)
**因此, 如果只是要在文件作用域内,进行 函数传参时, 使用 对象的本身,但是不需要延长生命期的时候, ** 就不要使用 指针, 而是使用 引用 就可以了, 这样就避免了指针的 "延长生命期"的 "副作用" . 当然还有其他需要使用指针的时候, 如多态的实现...
php中的对象, 因为都是用new来实例化的,所以都用 ->(叫对象运算符)来引用(对象的成员变量,也叫属性,字段,features), 静态用::(叫双冒号)来引用. 但是在tp的模板中使用冒号:来引用对象的成员.
后台模块 Admin 的配置参考 http://www.mamicode.com/info-detail-1181250.html
页面trace是怎样做到的过程?
定义'SHOW_PAGE_TRACE' => true,
模型类的定义问题? - 注意tp中的路径问题, 很多路径,都是 规定, 系统约定, 系统中的解析器, 会从约定的路径开始解析...
自定义模型类, 要使用"相对路径", 不用加 , 从模块开始写起:<?php namespace Home\Model; use Think\Model; class FooModel extends Model{...} ?>
而实例化自定义的模型类时, 要使用 "形式上的 绝对路径" ,从 \ 写起: $User = new \Home\Model\FooModel();
数据库的连接查询?
目的是为了从多个表中获取字段的信息,条件是两个表 中要有相关联的字段,字段的数据类型要相同,名称不一定相同.
内连接的方式:
mysql默认的方式就是内连接,即join=inner join, 使用join要结合on使用, on是指明两个表用 哪两个字段 进行连接查询; 不同于where,where是过滤 连接查询结果 后的条件. 如果不使用join, 则使用 "隐含"内连接, 连接字段就放在where中(这时候的where就相当于on...).
mysql支持 中文下标key吗? 是的:如{$vo["学号"]}
thinkphp中为什么要使用query函数?
如果是针对 单一的一个表, 的insert delete update select等操作, 就使用tp的 链接操作函数,
但是如果要操作的情况比这个复杂, 如查询的表不是一个表,操作的是多个表, 或者是不是普通的Crud,而是联合查询,那么这个时候,就不能使用链式函数, 而要使用原生的sql语句,调用query函数了.如下:
$Sql= M();
$query = "select foo.uid as '学号',foo.name,score.score from foo,score where foo.uid=score.sno and foo.name='john'";
$query = "select foo.uid, foo.name, score.score from foo join score on foo.uid=score.sno where foo.name='john'";
$result = $Sql->query($query);
dump($result);
tp支持标准的orm和AR及原生的sql操作,为什么要写这么多"眼花缭乱"的方法呢? 是因为在实际中的需求就有这么多,有的是功能的需求,有的是效率性能上的需求.
tp的"增删改查"就是add, delete, save, select,跟原生的sql操作名称不一样,一是,不能去"占用""覆盖"原生的操作名称,二是正好与日常的"叫法"相一致.
$User=M('user')就是数据表对应的类的实例化对象,从oop的观点来看,它本身就应该,也可以用来操作数据表的curd操作.
通常只有在add和save方法中,才需要创建数据对象DO, 调用`$User->create(); create($data);create($another_do); 也可以使用
data($data)方法`, 只有创建了do(在内存中),才能用add/save方法写入数据库
create和data创建do的区别?
create做的工作很多,包括了获取ds,ds合法性检验,检查字段映射, 字段验证,自动完成,令牌检查等. 而data则没有那么多的附加工作和
功能,要自己去完成.
select子查询的作用主要有四点?
1.用作生成子表(返回多条数据), 如 join (select....)as another_table...
2.用作生成一个静态数值, 在算术表达式中使用
3.用作生成 "一个" "相关子查询""动态子查询" 数值, 用在 条件等 算数表达式中
4.用作生成数值范围,用在exist,not exist语句中.
rand和mt_rand?
mt_rand比rand的速度更快(快4倍?),生成的随机数更好? 在windows下, RAND_MAX的值是32768, 并且rand和mt_rand都不需要播种.
php中生成m,n之间的随机数?
php生成随机整数值,比aspx,java更简洁,不需要去/100, 不需要去round,ceil等,直接用mt_rand(m, n)就得到了.
count(*)和count(column)的区别?
http://www.cnblogs.com/wzmenjoy/p/4244590.html count(column)不计 column为null的条数?
sum(参数), 如果参数是列名, 则表示整个列的数值的和, 如果是条件表达式,则是表示 列值满足条件表达式 的记录 行数的 总和
不能用count(条件表达式) 如count(score<60) 来统计不及格的总数, 因为 count(参数)中,只要参数 !=NULL 则都表示计算总的记录条数. 所以,count(0)=count(1)=count(2)...=count(*)... 的
group by ,having等的用法:http://blog.csdn.net/zuiwuyuan/article/details/39431639
group: 意思是: 分组,聚合,组合,统计函数
having和where的区别?
where是对记录进行原始条件过滤,在分组 group by语句前使用; where中不能使用聚合函数.
having是对分组后的结果,进行条件过滤, 在having中可以使用 聚合函数,也可以使用 一般过滤条件.
where score > max(score): error: invalid use of group function.?
这个问题就是,"为什么在 where 子句中 要使用where score > = (select avg(score) from table)' 而不是直接使用 where score> avg(score)', 上面已经做了回答: 因为在where字句中不能使用group function! 所以,要用子查询...
mysql 为什么要使用group by 分组?
因为实际项目中, 有"需要分组, 按类别"进行数据查询,统计的需求. 将"某列(某个字段)具有相同值的多条记录合并为一组,最后作为一条记录输出", 注意这里是说 作为一条记录输出. 通常分组是和 聚合函数一起进行输出的, 通常输出的字段是 '分组字段1', '分组字段2...', '字段的聚合函数' from table group by '分组字段1', '分组字段2...'. 分组字段的选择是关键,要选择"某一列的值都相同的" 那个字段作为 "分组字段", 否则就失去了分组的意义,因为就没有办法分组.
(如果select语句中的 字段 没有使用组函数,那么它就必须出现在group by字句中, 即作为分组字段,否则,就只会显示第一条记录 的那个 字段值). 也就是说, 如果group by 不跟聚合函数一起使用, select中不是使用的分组字段/group function,则就是没有意义的分组,就是根本不懂分组的人.
mysql->php->browser的中文乱码问题?
下面的说法是不正确的!!!
很简单: 在mysql中不管,不要修改,保持为默认的utf-8; php就是连接的桥梁,是保证无乱码的核心; browser不用手动去设置, 它的内容的编码, 可以通过php的header函数来指定,来控制.
也就是说, 只要保证 *.php文件 要写入到 mysql数据库的文件编码是 utf-8 就 一切ok
一是, 跟php文件的 编辑器/ide有关, 看editor能不能设置为utf-8编码;
二是, 如果编辑器不能设置为utf-8编码,就要用字符集转换函数
php的 iconv和mb_convert_encoding?
两者都不是php的原生函数库函数, 要通过扩展开启才能使用: php_icon.dll, php_mbstring.dll(可以通过phpinfo查看);
iconv的效率比mb_convert_encoding快, 只有当不知道原来的编码,或iconv转换出错时,才使用后者;
iconv(in_charset, out_charset, str): out_charset//TRANSLIT(TRANSLATE + IT, 表示不能准确转换时,转换成一个近似的字符也可以),//IGNORE表示不能转换时,忽略它.
**iconv和mb_convert_encoding, 他们的参数都是一样的, 但参数的方向正好相反. mb_convert_encoding(str, out_charset, [in_charset]最后这个"原来的字符编码集"参数是可选的)... **
php header的格式
header函数调用, 要放在方法函数中, 不能放在php标签后,函数外部.header("字符串 Content-type: text/html; charset=utf-8 ");
mysql的查询操作 "时间"概念?
通常,一个简单的查询操作, 费时: 0.000几秒, 即万分之几秒, 多一点的操作 是 0.00几秒, 即千分之几秒.
php的类中的成员变量和成员方法 都要显式的说明其 访问类型, public,protected,private, 默认的,如果不写访问类型,则是public.
PHP_EOL: end of line
在mac中: \r, unix-like: \n, windows: \r\n. 只是换行符, 但是在html中仍然只是表现为一个空格, 不会换行.
控制器中的方法,总是 先输出本方法中输出的内容, 然后,(如果有this->display()的话), 再输出对应的视图页的内容.
注意区别常量和"模板解析字符串"的区别?
因为这些常量和"convention"配置很容易混淆,所以要注意区别:
tp的常量包括: 预定义常量(如: THINK_VERSION,URL_COMMON...), 路径常量(THINK_PATH,LIB_PATH,CORE_PATH)等,系统常量(APP,ROOT,MODULE,CONTROLLER,ACTION,SELF, IS_POST)等等(这些系统常量中, 分成两种,有的只能用在PHP文件中,如: IS_POST,有的既可以用于php文件中,又可以用于View视图的html页面中, 如: URL之类的系统常量,SELF,MODULE,CONTROLLER,__ACTION__等, 而且这些变量可以用在html模板中的任意地方,既可以是地址之类的,如href,form的action,也可以直接在页面内容中输出...)
前面的常量, 只是限于系统已经定义了的(__PUBLIC__这个好像是已经定义了的, 好像不一定只是帮组手册上所提到的那些), 如果没有定义,你就不能在view视图页面内直接使用,要使用自己定义的模板变量进行地址替换, 就必须在配置文件的TMPL_PARSE_STRING中进行设置和规定.
系统常量中的URL地址之类的东西,总是从根路径 "/"开始输出的(并且除了__ROOT__之外,其余都是带index.php入口地址的), 如: ROOT