• tp框架中 关于数据库mysql 的一些疑点知识


    mysql创建索引, 通常是在 创建表的 同时/时候, 就创建了

    即使是在win下, 用命令行操作数据库 , 也要比 图形界面的鼠标操作快得多

    索引的类型有: unique, fulltext索引, spatial空间索引, 和普通索引 index/key


    fulltext全文索引的使用?

    1. 使用索引的好处, 如同字典 的 索引一样, 如果你从头到尾不使用索引 一个字一个字地 查字典 找一个字的话, 是很老火的. 反之, 使用前面的偏旁部首索引 查字, 可以通过 字 和 页数 的 对应关系 一下子找到该字. mysql的索引是同样的道理, 它创建了 数据和 数据所在的 位置/记录行之间的 对应关系....

    2. fulltext是全文索引, 也叫做 全站索引. 从 mysql4.0 开始支持.
      其中的 ft_min_word_len 叫做 fulltext min word length. 默认的是 4个字符, 对英文的全站索引比较合理, 对中文, 就不是很合理了. 中文最好设置成
      ft_min_word_len =2, 或 1
      方法是在 : 配置文件 my.ini(linux的 my.cnf) 中的 [mysqld] 节中, 增加这一句: ft_min_word_len=2, 或 1 就好了
      全文索引 通常是对 文章的标题(搜索文章标题 title), 或内容(搜索整个文章的内容 content) 进行创建 索引. 然后 对他们进行 搜索就变得 可能....

    3. 创建全文索引的方法是:
      - alter table article add fulltext index_content(content);
      或者直接创建索引
      - create fulltext index index_content on article(content);

    4. 使用 全文索引的搜索方法是:

    select title, author, release_time, content, field1,  field2... where  `content_field`(全文索引的字段名称) against  ('查询内容-搜索字符串')  order by id desc limit  10
    
    • 关键是 这里的 查询条件: where '全文索引字段' against ('搜索内容') 的用法
    • 网页开发中, 只要 把数据 选择/搜查出来后, 显示和 呈现 就比较简单和随心所欲了.

    关于编辑器中的字体选择,

    • 可以选择 Courier New 字体. 这个字体也是每个 Windows都会带的,字体很好看,除了o O 0的区别,也是很多人在编程中使用的。
    • 或Bitstream Vera Sans Mono
    • Bitstream Vera Sans Mono,以及他的衍生字体DejaVu Sans Mono——DejaVu扩展了一些Unicode中的字符。 这也是很多开发者推荐的字体,除了完全满足上面说的所有条件之外,又是TTF字体,基本字形是无衬线的,适合屏幕阅读,最重要的还是开源的字体!

    字母的宽度一致

    或称为等宽字体,由于代码文件是普通文本,不带样式的,所以宽度一致易于排列和对齐,能迅速找到位置,提高可读性。
    
    印刷术中这种等宽字体称之为monospaced字体,他是字体中的一个大分类(family),如常见的Courier和Courier New。由于考虑到现在的多语言环境,在不同的系统中,要将这个字体在不同字符集下映射到不同的具体字体上去,比如,一般我们的系统都会把中文的映射到“宋体”上。
    

    courier: 快递员


    tp中的add支持批量写入, 就是一次性写入多条记录, 用数组表示, 数组用 动态添加的方式定义, 方法名是 addAll. 注意是 AddAll , 不是 AddList

    $dataList[] = array('name' => 'foo', 'age' => 10);
    $datalist[] = array('name' => 'foo2', 'age' => 15);
    $Model -> addAll($dataList);
    
    1. 在 add方法和save方法中, 要过滤字段, 既可以直接在 操作中, 用 field(...) 连贯操作方法来过滤字段, 也可以直接在 模型类中 直接定义 (一般是 类自己的属

    性, 不是通用性的属性, 常用 protected 定义 ) protected $insertFields = array (...); 和 protected $updateFields = array(....);

    1. 在php和tp 的 很多操作方法和函数中, 比如find 方法 和 select方法等, 如果查询出错, 则返回false; 如果查询结果为空, 则返回null. 如果有结果, 则返

    回字段或数组/数组集. 要清醒地认识到 返回的结果 false 和null的区别,不要搞混了.
    **注意, find的结果, 即使满足条件的数据不止一个, find方法也只会返回第一条记录(当然可以用order排序等) **

    class Model {
    // 操作状态
    const MODEL_INSERT = 1; // 插入模型数据
    const MODEL_UPDATE = 2; // 更新模型数据
    const MODEL_BOTH = 3; // 包含上面两种方式
    const MUST_VALIDATE = 1; // 必须验证
    const EXISTS_VALIDATE = 0; // 表单存在字段则验证
    const VALUE_VALIDATE = 2; // 表单值不为空则验证

    // 当前数据库操作对象
    protected $db               =   null;
    // 数据库对象池
    private   $_db				=	array();
    
    
    public function field($field,$except=false){   ///这里的except是指定是否 进行排除...
        if(true === $field) {// 获取全部字段
            $fields     =  $this->getDbFields();
            $field      =  $fields?:'*';
        }elseif($except) {// 字段排除
            if(is_string($field)) {
                $field  =  explode(',',$field);
            }
            $fields     =  $this->getDbFields();
            $field      =  $fields?array_diff($fields,$field):$field;
        }
        $this->options['field']   =   $field;
        return $this;    ////  这里返回的是 模型对象本身, 连贯操作都返回的是 $this. 
    }
    


    在tp中, 几乎所有的函数和方法中的参数, 都同时支持 字符串和数组的 参数形式, 即既可以使用 字符串的参数, 也可以使用 数组的参数 形式.

    关于错误/成功/重定向 跳转处理?

    1. 全局的跳转函数: function redirect($url, $time=0, $msg='') {...

    2. 控制器类的 跳转成员:

       $this ->  protected function redirect($url,$params=array(),$delay=0,$msg='') {
            $url    =   U($url,$params);   // 这里就是借助于U方法, 将基本url和额外参数组装成复杂url地址.
            redirect($url,$delay,$msg);	// 然后调用的 全局的redirect方法.
        }
    
    1. 所以, 两个redirect方法其实没有本质的不同, 参数都是一样的(跳转地址url, 延伸time/delay, 提示消息message), 只是, 成员方法多了一个$vars 后来被U方法组

    装.

    1. 关于U方法. 熟练牢固地掌握U方法:
    • U($url, $vars, $suffix, $domain), $url地址本身支持 Module/Controller/Action#所有的锚点都用井号表示@别名的相同的域名? var1=val1&var2=val2... 而且还支持分开的 单独的额外参数$vars, 后面两个参数用来说明地址的开头和结尾, 结尾用$suffix ,开头用@domain来说明...

    • 具体的参数 **很多时候 就是用 U方法 来将 初步的原始的 基本的$url地址和 参数 $vars/ $params 组装成完整的 复杂的url地址,比如 上面的两个 redirect方法. **

    /**
     * URL组装 支持不同URL模式
     * @param string $url URL表达式,格式:'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...'
     * @param string|array $vars 传入的参数,支持数组和字符串
     * @param string|boolean $suffix 伪静态后缀,默认为true表示获取配置值
     * @param boolean $domain 是否显示域名
     * @return string
     */
    function U($url='',$vars='',$suffix=true,$domain=false) {
    

    关于tp中的跳转?

    1. $Model->redirect($url, $vars,$delay,$msg)中,如果要设置延时,则必须输入params, 因为delay参数是在第三位
      如果发现跳转后的url有问题, 可以先测试一下 U方法。 U($url, $vars, $suffix, $domain);

    如果不想使用U方法生成跳转地址, 也可以直接使用php的header函数或 全局的redirect函数。

    1. $this->redirect方法和success, error的区别是
      redirect 是利用php的header重定向,而success和error是使用的html的meta http-equiv属性。 meta http-equiv='refresh" content="5; url=www.foo.com"
      redirect 无模板页面, 输出的提示信息是直接在函数内echo输出的
      而success和error都有对应的模板输出。
      三者都可以实现页面跳转, 只是redirect可以无延时的重定向, 具体采用哪种情况视具体而定。

    2. success和error 的模板文件可以定制:

    • tp中的分隔符, 是用 depr来表示的 , 不是 dept: 猜测: depr: 是 data/delimiter separator的缩写, 所以 最后那个字符是R不是T.

    • runtime下的 Home目录中的???.php文件 实际上是 从 控制器/操作方法到 生成 模板文件的 中间文件. 每个 {$foo}内容实际上 是转换成了 <?php echo (...); ?>

    • 即使是开启了缓存, 'TMPL_CACHE_ON' =>TRUE, 'TMPL_CACHE_TIME' => 1等设置, 也并不是表示 模板缓存runtime/home/....php文件会随时重新生成新的不同名字的文件, 仍然是同一个 文件名称.

    • strip主要是动词, 表示 "剥夺, 剥掉, 剥皮"等的意思, 而stripe 主要是条带 讲, 没有剥夺的意思.

    • die和exit的区别: 两者实际上是一样的! exit是原函数, die是exit函数的别名alias. 两者可以接受 一个数字或字符串: 具体用法上, 如果是脚本运行多用exit, 如果是web运行, 多用die. 如果传入数值, 表示的是一种 运行结果的状态码 (比如123, 这个状态码数字是不会输出的), 要输出, 得用 字符串方式比如exit('123'), die('123')...

    • success和error 可以使用项目内部的模板文件, 用 TMPL_ACTION_SUCCESS => Public:success 等来定义, 注意, 模板表示文件路径用冒号来表示 , 其中 定义error也是类似的

    • 模板文件中可以使用的 模板标签是: 5个: $msgTitle, $message, $status(1表示成功, 0 表示失败) , $waitSecond, $jumpUrl

    • success和error会自动判断当前请求是否是ajax请求, 如果是ajax请求, 会调用 ajaxReturn方法 返回信息, 返回的数据$data会封装三个变量

    $data['info'] = $message;
    $data['status'] = $status;
    $data['url'] = $jumpUrl;
    

    tp中的查询语言(查询方式)包括很多种,主要有以下这些

    1. 子查询 就是生成$subQuery 语句(子语句), 然后生成的子语句 又用在其他查询语句中.
      子查询有两种方式
      一是在连贯操作后, 使用select(false), false就表示不进行真正的查询结果,而是生产查询子语句;
      二是在连贯操作后, 用 buildSql()方法

    2. 虚拟模型
      是指虽然是模型类, 但是不会进行真正的数据库curd操作,只是借助模型类来封装一些业务逻辑。 实际中几乎没有什么用。
      建立一种思想认识, 就是tp的mysql数据库连接是惰性的: 即只有具有数据库操作: 读写 的时候, 才会去建立数据库连接

    3. 动态查询 这些方法都是通过 __call机制得到的
      就是直接依据表中的某个字段(的值作为查询条件), 返回符合条件的记录(集)或字段的值,主要有两个方法:

    • getBy... 比如根据“name”字段获得记录(集): $User -> getByName('obaa');
    • getFieldBy... 比如根据“name”字段获得字段值: $User -> getFieldByName('foo');
    1. tp中查询条件的表示方法一般、大致有这样几种: $where, $cond, $map.

    2. 在php中,甚至所有的编程语言中, return语句的写法, 后面可以 直接跟 变量,表达式, 甚至直接跟一个复杂的 语句, 比如 return $this->where($where)->getField($args[1]);

    3. 原生sql语句查询

    • 凡是 tp 非原生语句, 都是支持/默认 表前缀的, 比如 think_, 那么凡是 原生语句查询, 都不能支持 表前缀, 那么都要用 表的全名, 或者使用 下划线的方式: 比如: USER, 或 __PREFIX__user.
      tp的模型类也支持 原生的sql语句查询,提供了两个方法:(但是要注意 原生查询就不能使用连贯方法了)
      一个是 query, 只进行查询语句
      另一个是 execute,只进行 增加记录 和 更新记录的操作
      如果设置了 读写分离的话,那么,query始终在读服务器上操作, execute始终在写服务器上操作
    1. 统计查询?
    • **跟上面的 动态查询一样, 统计查询也是使用Model的 __call重载机制实现的, 有 if (in_array(strtolower($method), array('count', 'max', 'min','avg', 'sum'), true表示严格检查类型和大小写匹配)) {... return $this->...} elseif .... **

    • Dejava是法语词, 表示 心灵之境, 似曾相识. Sans Mono 是一种编程中常用的字体

    • php中, else if既可以分开写, 也可以 连起来写: elseif 这样做是为了效率更快

    • in_array函数, 如果是字符串包含检查, 则 最后面不管是false还是true, 都会严格检查字符串字符的 大小写, 如果大小写不符, 都会认为不包含.

    • 统计查询中, count可以有参数 , 常用的是id, 也可以不用参数. 而其他统计 方法必须有参数.

    • 统计查询, 都支持 连贯操作的使用!


    1.组合查询
    其条件的主体$where还是数组, 但可以组合使用字符串条件_string, 查询_query , 或其他的数组条件_complex
    组合查询, 就是多种格式的条件 一起混合使用.
    【说明】

    • 但是组合查询中, 除了主体的数组条件外, 其他的特殊查询一次只能定义一个.
    • 由于才用数组索引的方式, 索引/下标相同的特殊查询会被覆盖

    关于tp中字段过滤的处理.

    首先, 当要插入或更新的data中, 包含了数据表中 没有的字段时, tp会自动过滤掉该字段;
    其次, 也有不过滤的情况:

    • 如果你使用了 strict 的连贯操作方法,将严格检查???
    • 如果你开启了 APP_DEBUG 为true的调试模式, 将抛出异常: ??? '_ERROR_QUERY_EXPRESS_' => '错误的查询条件',
    1. tp中的E函数和L函数?
      E函数是 抛出异常, 结尾是 直接是 throw, 不是 return.  在tp中 错误, 叫做" 异常" ??
    function E($msg, $code=0) {
        throw new ThinkException($msg, $code);
    }
    
    

    L函数 ,可以获取和设置语言?
    L函数中设置的 语言项 是 用下划线 开头和结尾的, 而且是大写

    1. php中的foreach: 有for结构语句, 没有each语句, 所以要使用遍历数组的话,使用的结构是foreach语句.

    2. 分析链式操作的方法名,是在成员函数 protected function _parseOptions($options=array()). 在这个函数中进行了连贯操作的解析. 生成对应的 数据库操作 查询方法或条件

    3. Model类的连贯操作(链操作)方法名,是放在 protected $methods=array('strict','alias', 'table', 'where', 'order','limit'....)数组中的.

    4. 类的成员变量和函数, 除了必须在外部访问的,用 public外, 其他的应该用 protected(本类和子类)和private(只有本类可以访问)都是私有的

    5. 类的常亮, 不能用$符号, 约定使用 全部大写 来表示 常量MEMBER. 只能用类来引用, 在类中 , 如果类目很长, 也可以用self来代替. self$this的区别是, 前者表示类自己, 后者表示类的一个 实例.即 AClass::MEMBER 和 self::MEMBER是一样的. 但是 self只能在类的内部使用, 因为在类的外部self没有上下文的约束, 就无意义了.

    6. 注意 类的常量 const 是 public的,而且, 一般都不用 public去修饰. 因为可以在 类的外部用 AClass::MEMBER 举个例子.

    // 可以在类的外部, 比如index.php中访问类的常量: 
    print HomeControllerIndexController::INDEX_TYPE;
    
    在IndexController类中, 可以直接用self访问:
       print IndexController::INDEX_TYPE.'<BR>';
       print self::FOO_TYPE;
    
    
    1. tp支持区间查询?
      就是针对同一个字段的多个查询条件的组合. $where用数组表示, 其中的条件可以是字符串,数组,表达式等任何形式的. 最后的一个数组元素(参数)表示 条件组合类型,有'OR,XOR,AND', 默认不写的时候表示 AND.
    $where['name'] = array( array('like',  '李%'), '张三', array('exp', 'in("李四", "王五")'),'OR');
    
    1. 在tp中, 配置文件或语言文件中,表示某个意思的单词, 通常用缩写, 或者"基本单词", 后面一般不加后缀的,比如tion, re等...
      比如'BUILD_DIR_SECURE' (不用security), 'ERROR_QUERY_EXPRESS' 不用expression.

    php的header函数:

    是将html中 meta 标签的 http-equiv 属性值和 content属性值, 放在一起来写的. 但是不要 meta和http-equiv和content,所以显得更加简洁. header('Content-type: text/html; charset=utf-8 ');

    使用的L语言配置项要写正确, 特别是最后的下划线, 否则,会按原样显示... 比如: L('_ERROR_QUERY_EXPRESS'); 将会是错误的, 还是按原样输出_ERROR_QUERY_EXPRESS


    通常在php中引号用单引号(只有要在字符串中解析$foo变量的时候才用双引号), 但是在操作数据库语句 sql语句中的时候, 要使用双引号,包括在html中的属性时也要使用双引号.

    php中的echo和print?

    • 两者几乎是一样的, 凡是echo可以使用的地方, print也可以使用, 反之亦然
    • echo和print都是 语言结构(什么叫语言结构? 就是 关键词, 比如case, if, foreach等之类的...) 所以, 后面不需要 加 括号.
    • 通常还是在php中用echo. 只是如果你熟悉/习惯 了 c/c++ 语言风格的话, 你可以使用print语句.
    • 两者的细微区别是: print 同时/一次 只能输出 一个 字符串, 不能输出多个字符串; echo可以 同时输出多个字符串.
    • echo 不需要括号, 如果加括号, 则只能每个字符串都加括号, 不能把多个字符串放在一个括号中. 否则会 报错! 和print的错误输出一样" 非法的逗号".

    1. tp中的表达式查询?
    • 主要是为了 解决复杂条件查询, 比如 like, 大于等于, not between等之类的条件
      表达式查询, 用数组来表示.

    • 实际上就是将 字段 比较运算符和 比较的具体值 分开来写: 比如 字符串条件 $where = 'age>=10' 中包含三个部分, 一个是数据库字段, 一个是比较运算符 一个是比较值. 表达式查询方式就是: 将字段写在数组的'下标'中, 然后将比较运算符和 比较值分开写, 来放在另外的数组中: $where ['age'] = array('egt', 10);

    • 也可以将 比较运算符和 比较值放在一起写 (像原生的sql), 那么 后面的array, 就用 'exp' 来表示. 比如: $where [age] = array('exp', 'between(10, 20)');

    1. tp中的条件查询?
      可以使用 字符串/字符串预处理/数组/对象 等 方式都是可以的, 但是 tp推荐的是使用 数组方式, 更高效更安全.
      多字段条件的数组方式, 默认的逻辑是and, 但是可以用 $conditon['_logic'] = 'or'; 来改变.
      如果用对象的话, 要初始化一个 用在 条件 $where中的对象, 使用 $where = new stdClass(); 来定义

    2. tp中的快捷查询? 就是 多个字段的条件值 相对应赋值

    • 只支持两种 逻辑运算符, 也就是只有两种情况: & 和 |
    • & 和 | 只能放在 前面的 数组 的 索引字段 中 , 而不能放在后面的条件中, 因为条件是用array(....) 数组来表示的.
    • 而且 & 的话, 后面数组条件的最后一个值 必须是 '_multi' => true $where['a&b&c'] = array(1, '2', 3, '_multi' => true);
    • 对于 | , 只只适用于 多个字段对应同一值的情形, 如果是 同一个字段 对应多个 值的 情形, 请使用 字段的区间查询... $where['foo|bar'] = 'foobar';

    tp查询语句中的 like? 特别补充两点

    1. like的array数组, 支持 多个值的情形: 而且支持用and /or等逻辑连接: $where ['name'] = array('like', array('think%', '%foo%', 'other-foo'), 'or' );
    2. like 的字段模糊查询, 你可以手动的写百分号, 也可以在配置中设置模糊查询, 这样在like 查询条件中, 就不用写百分号了. 设置是: 'DB_LIKE_FIELDS' => 'title|content|memo等字段' 那么对应的查询条件就是: $where = array('like', array('think', 'foo', 'other' );

  • 相关阅读:
    webpy使用笔记(一)
    如何衡量离散程度
    Hash哈希(二)一致性Hash(C++实现)
    Hash哈希(一)
    sqlmap使用笔记
    Windows7 IIS7.5 HTTP Error 503 The service is unavailable 另类解决方案
    [转]IP动态切换脚本
    全国各地电信DNS服务器地址
    比较好的汉字拼音化类
    c#读取INI文件类
  • 原文地址:https://www.cnblogs.com/bkylee/p/8820409.html
Copyright © 2020-2023  润新知