bash脚本中 的 set -e表示 exit immediately if a simple command returns a non-zero value.主要是为了防止错误被忽略.会被当即退出, 可是最好在开发结束后, 删除这个指令, 以避免留下隐患.javascript
有四种命令提示符, 有PS1, 天然就有 PS2 PS3 PS4, 分别表示 PS2即 在后续的命令下一行的提示符(continu'ation interactive prompt), PS3是在select选项时 的提示符, PS4是调试时的提示符.php
shell中要进行算术运算, 有5种方法: (由于默认的算术运算符号+-*/ 都不会被直接当作运算符, 而只是当作普通字符来看待, 因此须要特殊处理)html
$(( ... )); $[...]
expr 1 + 2
注意有空格(特殊符号要用* 转义)shell的调试?java
#!bin/bash -xv
???$_SERVER['HTTP_REFERER']为何为空?mysql
http_refer彻底依赖于浏览器自身, 有的浏览器是没有设置这个变量的. 你就得不到它.web
可是, 在不少状况下http_referer会无效, null. 好比你 直接访问一个页面的时候, 或从收藏夹中访问页面的时候,
因此通常来讲,只有经过 <a> 超连接 </a>
或者: location.href=...
跳转, 以及 POST 或 GET 表单 提交访问的页面, $_SERVER['HTTP_REFERER']
才有效。 sql
因为 $_SERVER['HTTP_REFERER'] 对 POST 表单访问也是有效的,所以在表单数据处理页面 必定程度上 能够经过校验 $_SERVER['HTTP_REFERER'] 来防止表单数据的恶意提交。但该方法并不能保证表单数据的绝对正确,即对表单数据的真实性检测并不能彻底依赖于 $_SERVER['HTTP_REFERER'] 。thinkphp
========================shell
因此, 在tp中, 操做成功或失败的提示 跳转是用 success和error. $this->success/errror('跳转提示信息', 跳转的地址_默认是http_referer, 跳转等待时间)
数据库
<script type="text/javascript"> (function(){ var wait = document.getElementById('wait'),href = document.getElementById('href').href; var interval = setInterval(function(){ var time = --wait.innerHTML; if(time <= 0) { location.href = href; clearInterval(interval); }; }, 1000); })(); </script>
关于tp?
tp的文件上传 在"专题"中.
tp使用 "类" 的思想: 先new一个 类对象, 而后让 类对象与实际要操做(上传)的文件相关联, 而后经过操做这个 已经关联了的类对象实现对该文件的各类操做.
tp中的array数组, 是应用得最普遍的. 能够说凡是能用 "字符串"的地方, 几乎均可以用数组来 表示, 用数组来操做, 并且都推荐用数组, (由于数组更安全??)
其中, add和save方法, 须要先建立 插入和更新的 数据对象$data
(实际上就是要插入/更新到表中的 记录)
这种建立数据对象的方法, 有两种, 一是 create()方法, 一是data()方法. 两个方法的相同点是: 均可以/都支持多种数据来源, 包括从 数组, 其余数据对象甚至 普通对象来建立; 不一样点是: create的功能更强大, 不但支持建立的数据对象的自动验证和自动完成($_validate和$_auto), 并且还能够 自动地从 $_POST数组建立数据对象.
$User = M('user')
的时候, 就须要数据库配置, 若是没有配置/没有正确配置, 就会报错.static public function getInstance($config=array())
参数就是$config数据库链接配置!E(L('_NO_DB_DRIVER_') . ':'. $class), E函数的原型是 E($msg, $code); 因此全部的错误提示内容, 都要放在整个 E() 函数的括号内
错误函数是 抛出了一个 异常 throw new Exception($msg, $code);
因此: E函数后的全部内容 都将 中止执行, 直接从 E()函数处退出了, 并且是调用 统一的 异常输出模板.一是使用 field函数,( 要注意, field方法没有复数, 因此其参数也是 一个 字符串. 另外field是指定 接收的/生效的字段, 不是 将被过滤被丢弃的字段 ) 而后用create()建立,
二是配置 insertFields, updateFields两个的值,
**即便设置了表单 的字段映射, 可是在 后面的全部 连贯操做的 field方法中, 表示 参数的 字段都 应该是实际的数据表字段, 而不是 字段映射, 不是表单中的 字段域, 不然 当定义了字段映射时, 又使用 filed('表单字段'), 那么就会出现 create的数据对象 为空 empty的 错误!
要注意, 若是要设置 $insertFields 和 $updateFields的值, 以及要实现自动验证和自动完成, 都要 创
建 自定义的 模型类, 不能直接使用标准 的模型类的基类.
'load_ext_config' => 'mylang'
tp的配置尽可能用 小写字母, 由于无论大写仍是小写, 最后都要转变为小写. 虽然为了好看,"推荐"用小写. 可是在实际开发中, 一切都是 以 "效率" 为最高原则的.
https://www.jb51.net/article/47624.htm http://www.cnblogs.com/yuwensong/p/4156383.html
这个仍是比较复杂的, 一般是不须要的.若是确实要这样作, 步骤是:(可是好像有错误???)
1.在/App/Home/Conf/config.php配置中, 追加
'LANG_SWITCH_ON' => true, //开启语言包功能 'LANG_AUTO_DETECT' => true, // 自动侦测语言 'DEFAULT_LANG' => 'zh-cn', // 默认语言 'LANG_LIST' => 'en-us,zh-cn,zh-tw', //必须写可容许的语言列表 'VAR_LANGUAGE' => 'l', // 默认语言切换变量
2.在Home/Conf目录中建立一个php文件, 好比: tag.php 内容以下
<?php
return array(
// 添加下面一行定义便可
'app_begin' => array('CheckLang')
);
3.把框架中的 Extend/Behavior/CheckLangBehavior.class.php 文件复制到 Home/lib/Behavior/中(完整版的thinkphp包才有,没有的话请自行建立) 4.而后就是 建立对应的语言项文件了, 在 /App/Home/下建立对应的三个语言文件夹: zh-cn, en-us, zh-tw. 而后再在这些语言目录中建立对应的语言文件, 文件名必须设置为common.php?? 5.最后就是 引用/使用 语言配置了, 在模板文件中, 使用 `{$Think.lang.语言项}` 在后台控制器中, 用L()方法来引用.
==================================================================
echo $User->name
;$var_data = $User->create()
, 这样你就能够很直观地dump出 $var_data 查看数据了where子句,不但能根据条件选择筛选记录, 并且 在 id自增的时候 能够用来选择最前/最后/中间 N条记录: ... where id > Max(id)....
一般来讲, where, limit等的操做耗时 比order的耗时 要小, 应该尽可能避免 order操做??
在非mysql的选择子句中,最前面N条记录 能够用 top子句 , 可是 mysql没有top子句! 只能使用limit子句. 参考 http://www.cnblogs.com/freeliver54/archive/2008/07/23/1249232.html
limit 9, 11
从第10条开始的共10条记录: limit 9, 10
male和female不仅是指人, 还能够用来指 雄性动物或 雄性植物(雄株) . man和woman一般用来指成年男人和女人. 也就是说 male包括 man和boy. female的fe.
字段映射的方式是: 在自定义模型类 中添加protected $_map=array('表单字段名' => '数据表字段名');
注意是把 表单字段 映射为 数据表字段, 不多是反过来吧,自己你就要隐藏数据表字段呢, 你难道还想 主动暴露到表单中来吗?
使用字段映射: 即便使用了字段映射, 并不会 自动 影响 查询结果, 查询结果中的 记录中的 字段名称仍然是 原来的数据表中的字段名称, 不会是 "表单"字段名. 除非你在配置中设置了 read_data_map' => true,
或者使用 D('user') -> parseFieldsMap($data_result)方法手动 转换.
在$User->create()
后, 里面的数据对象就已经被 映射了, 即原来表单中的字段就已经自动转换为数据表中的字段了,(这个是create所做的工做之一),因此接下来就能够用 连贯操做 add了 .
$_POST是: array (size=2) 'username' => string '' (length=0) //这里明确给出了是: string , 并且是 '', 不是 null! 'gender' => string 'm' (length=1)
===============================================================
bufdo bd
其中 bufdo是指 针对全部的 缓冲区执行的命令.主要是这个: http://www.cnblogs.com/Qian123/p/5669259.html 和http://www.cnblogs.com/Qian123/p/5669259.html
明确了sql语句的执行过程, 你对数据库的执行过程和原理就会更深刻, 也会避免一些使用上的错误, 好比:distinct子句 的原理 是 在内存中, 利用一个 临时表来 获得一个 vt的
mysql中的统计函数, 好比max, min, sum, avg, 也叫 分组函数(group functions). 也就是说, 只有在 执行了group by子句后, 其余子句才能使用: 即在第5步后 才能使用 分组(统计)函数. 而where子句是在 group by子句以前执行的, 因此 在 where 子句中, 就不能使用 group子句中才能使用的 统计函数. 好比 where score>=average(score)??
就会报错: "invalid use of group functins"
分组后, 在分组记录中, 咱们能够 select出关于分组的统计信息, 也能够select 原数据表中的非统计信息(即普通字段信息), 虽然分组操做的目的一般是要 select出统计信息. 若是分组后 select的是 非统计字段信息,则 在第9 步(select步骤)老是显示的/保留的是 相同分组中 排在最前面的那个记录的 字段信息. (可是 在分组后所得的虚拟表VT(第5步时)分组中的 其余记录/信息仍然是保留的. 是按分组字段的不一样 挨着挨着排列的(相似于excel中的分组), 因此, 一直到第8步select的时候 还能够用 count, max等统计函数对全部 记录 和 相关字段进行统计 )
+------+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+ | 1 | SIMPLE | user | range | PRIMARY | PRIMARY | 4 | NULL | 7 | Using where; Using temporary; Using filesort | +------+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+ 1 row in set (0.00 sec)
关于explain中的说明?
select Max(id) ...
而是用索引来作, 好比: 建立id的索引(show index from table_name
), 而后用 select... order by id desc limit 1
来代替, 这样效率更高https://blog.csdn.net/john_hongming/article/details/42742965
MariaDB [test]> select * from user where score in (select max(score) from user group by gender); +------------+-----------+--------+-------+ | id | name | gender | score | +------------+-----------+--------+-------+ | 0000000002 | 孙徐连 | w | 98 | | 0000000010 | 王的徐 | m | 97 | +------------+-----------+--------+-------+ 2 rows in set (0.00 sec) MariaDB [test]>
show index from user;
select id, name as '姓名', score-60 as chazhi from score having chazi>30;
MariaDB [test]> select id, name as '姓名', score-60 as chazi from user where chazi>30; ERROR 1054 (42S22): Unknown column 'chazi' in 'where clause' // 很明显, where只是针对 字段来判断的, 若是是select中的 运算表达式, 则会报错, "未知的字段" MariaDB [test]> select id, name as '姓名', score-60 as chazi from user having chazi>30; +------------+-----------+-------+ | id | 姓名 | chazi | +------------+-----------+-------+ | 0000000001 | 孙以的 | 34 | | 0000000002 | 孙徐连 | 38 | | 0000000010 | 王的徐 | 37 | +------------+-----------+-------+ 3 rows in set (0.00 sec) MariaDB [test]>
===================================
====================================
tp的功能也不是尽善尽美(实际上世上也没有尽善尽美的东西吧), 还有一些bug的.
在 项目App/Runtime/Home/目录下的 那些php文件, 实际上就是 View目录下的 "模板" 的编译结果文件(所谓编译, 就是将模板中的php代码 解析成普通的html后)
(模板)布局layout是tp的功能, 实现布局的方式是用 模板, 这个模板叫" 布局模板" . 无论哪个框架的模板布局, 仍是颇有用的. 它是生成 基本框架都相同的多个页面的一种快速方法: 把多个页面中, 相同的要素(结构)好比页面的头部, 菜单栏, 页脚等内容是基本相同的, 提取出来, 而后多个页面中只有 主体内容 不一样的部分进行组装. 没有必要每个页面都完整的写一遍, 这个正是 符合软件 "结构化/模块化+重用" 的思想.
布局模板的实现有三种方式, 其中第二种方式, 是使用 layout标签, 这个标签的使用方法 ,跟其余html标签同样, 也是指定相应的属性就行了
layout标签不须要任何配置;
layout标签的属性有 name(使用哪一个布局模板), 和 replace(布局模板中的替换字符串)
在 头部增长(好像不必定是要在 head中, 在body中定义也是能够的! 并且 layout标签甚至能够在body内容的最下面/最后面书写都是能够的. 可是必定要在配置中, 关闭 LAYOUT_ON设置,不然 布局不会成功, 不会应用 布局模板!!! ):<layout name="Layout/newlayout" replace="{__REPLACE__}" />
使用了layout标签后, 一样的, 是把 当前模板文件的内容 替换到 布局模板中的 {REPLACE}
使用include标签 中的 layout标签, 能够实现模板标签的嵌套.
在convention.php配置中, 关于布局(模板) 的配置 有3个:
'TMPL_LAYOUT_ITEM' => '{__CONTENT__}', // 布局模板的内容替换标识 'LAYOUT_ON' => false, // 是否启用布局 'LAYOUT_NAME' => 'layout', // 当前布局名称 默认为layout
{_ _NOLAYOUT_ _ }
; 二是 在 控制器的操做中 使用 全局函数layout(是框架中的functions.php文件中的函数), 好比 layout(true), layout(false)禁用布局功能, layout('layout/new_layout')
并且使用全局函数layout时是不须要开启layout_on=>true
这个配置的.