tp框架中的一些疑点知识-8
- NaN是Number对象的一个属性, 表示一个特殊值, 表示不是一个 数字, 引用/赋值时, 要使用: Number.NaN
判断 一个值是不是 NaN, 用 isNaN() 函数, 它是一个js的全局函数 , 所以前面不需要用 对象什么的来引用, 直接使用 isNaN() . 同时要注意, 判断一个数是否是NaN不能用 == NaN, 因为NaN, 不等于任何值, 即使是它自身也不相等, 即: NaN != N阿N
注意这个函数不要 想反了. 是判断一个变量(不是一个数字).
当在一个 (任意的)变量(比如: 即使是一个函数表达式 )前面加上 + - 的时候, 就是 (隐含表示 将这个变量转换为数字), 这时候, 如果bu是一个有效的数字(比如在一个函数前加上一个 +/- , ), 就会输出 NaN
如果在一个 (任意的)变量 前面加上 ! 就表示 对后面的内容 按 逻辑值 求反值.(比如: 即使是一个函数表达式)
! 表示求反值的时候, 可以连续使用多个 感叹号! 比如 !!true 还是true, !!false就还是false
- prompt,alert, confirm是 js的顶级对象 window的 属性/方法. 所以 你可以省略(当然也可以带上)window. 这三个都是 模式对话框
prompt("只能是非html的提示text", "defaultvalue") 返回值: 单击cancel时返回 null. 可以通过console.log()来查看.
关于document.write的理解?
- js的document.write("任意的html代码, 支持 += 字符串操作符") . 要深刻理解他的作用机制: 向 当前 正在进行的 页面的输出流中 加入 html内容.
- 所以, 如果是要在 js的 延后脚本中, 调用document.write的话, 就要注意了: 因为 当文档被 载入 完成后, 那么当前 输出流就被 关闭(销毁)了. 这时候, 如果 再延时执行(不是第一次载入的时候执行) document.write的话, 就必须再重新 打开一个 文档输出流 进行写入, 相当于重新载入一个新的 html内容. 所以, 原来页面上的任何内容(包括变量和脚本) 都将不存在了???? (为什么 原来页面的变量还存在???)
参考: https://www.v2ex.com/t/303750#r_3525935
当你打开一个页面,浏览器会
1. (前面做了很多事情,与本文无关,省略)
2. 调用 document.open() 打开文档
3. document.write(...) 将下载到的网页内容写入文档
4. 所有内容写完了,就调用 document.close()
5. 触发 dom ready 事件( DOMContentReady)
所以你如果在第 4 步之前 document.write(1) 那么你就直接追加内容到当前位置,
如果你在第 4 步之后 document.write(),那么由于 document 已经 close 了,所以必须重新 document.open() 来打开文档,这一打开,内容就被清空了。
不信你可以这样验证一下:
1. 打开 baidu.com 等页面加载完
2. 在控制台运行 document.write(1),会看到页面清空,只有一个 1
3. 再次运行 document.write(1),会发现页面没有清空, 1 变成了 11 ,因为追加了一个 1
4. 运行 document.close(),这时文档就关闭了。
5. 再次运行 document.write(1),你会发现文档又清空了,变成了 1 。
js中获得当前时间 的函数, 每种语言都要 获取 当前时间. 但他们的函数名称都不一样. 只有自己记住了. 比如: php中用time()函数, js中用 内置对象: new Date(); 然后用对应的方法. new Date().getYear();
关于js中的 eval函数
eval: 是 evaluate求值的意思, 它是js的原生函数, 其参数是字符串, 本来字符串是没有 "求值/计算/执行" 功能的, 是literal的. 但是 经过eval函数包装后, 其中的字符串就是 js代码来执行了(先去掉引号, 然后执行没有引号部分的js内容).然后返回值.
- 相当于 bash中的反引号 的作用
- 有几种情况: 一是计算其中的算术表达式的值, 并返回; 二是把codestring参数当作命令 来执行; 三是将字符串转为 对象
- 目的是: 在一些特殊情况下, 更灵活, 更方便 获取索引到 dom(document object module)的对象
- html元素有id, class, type, value, name等属性, 其中id和class主要是给前端js脚本用的, 而name主要是给后台脚本用的. 要注意, 表单元素 本来 就有 value这个属性.
除了用jquery写 也要应用/不能完全抛弃 原生的js函数. 不能滥用jquery, 因为有些原生的js脚本 更快. 比如事件, 主要的事件要掌握, 像鼠标事件(onclick, ondblclick...) 键盘事件(onkeyup...) body事件(onload: 这个是指整个文档包括include的文档, 载入完成后的事件,不是指 刚载入时的事件,其实应该是onloaded. onresize, onerror, onscroll onstop, onmove等)
如何让表单中的控件 获取js中 的变量值? 比如hidden控件的当前时间值?
首先你不能直接通过 表单的属性获取 变量值、执行js代码, 因为虽然有 onclick事件属性, 但是你没法单击, 一是不符合操作习惯,二是对于隐藏控件你根本就单击不到嘛。
那么只有通过 js代码来给hidden控件赋值, 而且是通过 页面载入时就自动执行的 script脚本.
{__NOLAYOUT__}
<form action="{:U('check')}" method="post">
<p>
user:<input type="text" name="user" />
</p>
<p>
passwd:<input type="password" name="passwd" />
</p>
<p><input type="hidden" name="submit_time" id="htm" value="tm()"></p> // 这样想获得tm()函数的执行结果是不得行的, 最终是把 tm的内容字符串literal付给value.
// 实际并不会 获得执行后的值.
<p>
<input type="submit" />
</p>
</form>
<script>
/*
function tm(){
document.getElementById('htm').value = new Date().getTime();
}
window.onload = tm;
*/
// 或者前面的都不要, 函数什么的都不用要! 直接就中间的 那一句话 就可以了:
document.getElementById('htm').value = new Date().getTime(); // 注意dom 的根, 是document, 不是window!
</script>
#### 不同的浏览器对 type="submit"的 渲染/显示是不一样的, 比如ff和google的效果就不一样, 所以最好还是 明确地给 submit的value 赋值.
在form的表单控件中, 一定要写 name属性, 因为这个是给后台action目标页面 的$_GET $_POST用来获取 数据的 名称索引, 如果没有name属性,那么相应的控件的值是获取不到的, 是没有的.
程序中的时间戳为什么基本上从1970年1月1日23:59开始计算的.
因为 .... unix系统在1969年成雏形. 因为时间戳主要是用来记录文件时间的. 而在这之前很少有记录文件时间的需求. 所以 包括js, php等的时间戳都是从 1970年1月1日... 开始计算的.js的时间戳是从1970年1月1日到现在时间(某个给定时间)的毫秒数, 有三种获取方法:
- 使用Date对象的静态方法parse: var timestamp= Date.parse(new Date()); 这种方法的最后三位毫秒 全部置为000
- 使用 Date对象的 valueOf()方法 或getTime()方法. 这两种得到的也是毫秒数. 是一样的:
new Date().getTime() == new Date().valueOf();
verify 校验码的ajax刷新 问题
在检验验证码的时候, 要调用 Verify类 的check函数. 生成类的对象, 不一定 跟检验类的对象是同一个. 因为它们都会 去读写$_SESSION, 所以 读写的其实同一个值, 所以可以的. 但是 由于 同一个页面, 可以允许多个验证码, (虽然一般都不会这样做), 所以可以给验证码指定一个id, 表示 是第几个验证码. 那么, 在 check的时候, 就要把对应的id值 传递过去.
关于 验证码的检验问题?
注意 密码 类型的input, type必须是 password 才有效, 不能是 passwd.
在 minibufferExplorer中, buffer是按顺序进行排列的, 也就是 紧挨着的 两个buffer 之间可以用 bp 和 bn进行切换.
而即使不是紧挨着的两个 buffers 之间, 即最近的两个buffers之间 是可以 用 ctrl +6 来切换的.
- 为什么不能用 getElementByName来获取元素?
https://blog.csdn.net/ghostyusheng/article/details/50449428 这个问题的根源实际上还是HTML代码写的不规范引起的,一直以为是js的问题,实际上却忘了检验HTML的规范性,HTML标签有的有name属性,比如input、select、button等,而很多是没有的,比如td、div等,只有有name属性的标签才可以使用getElementsByName方法。
ps:name属性,name属性是input标签的内建属性,早期浏览器的getElementsByName方法是为了 **方便的获取用户的输入**。由于name只是input的内建属性,其它标签没有,所以getElementsByName方法不能在别的标签中识别这一属性,因此getElementsByName方法只能用于 **(在表单form中的 ) input标签,这也** 就是为什么你getElementsByName(‘ok’)得不到任何值的原因。
- 可以有多个具有相同id的元素, 那么实际起作用的只是第一个元素, 其他都是 "伪id"
- 如果只是有一个 要获取的元素, 建议 使用id, getElementById
- 不管是对form表单中的元素, 还是非表单中的元素, 都可以使用; getElementByTagName(...)
- 通常对于多个具有 相同name的元素, 获得的是一个 数组元素, 所以要判断 getElementsByName('certainName').length是否不为0
一直有个问题其实是错误的理解, 就是通过name获取 表单form中的input 标签的value时, 使用的函数名是: getElementsByName('some-name'), 不是 getElementByName. ` 注意, 这里的elements是复数, 不是element的单数, 否则, js会报错: getElementById不是一个函数!
- 而且, 对于getElementsByName 可以对 hidden类型的input控件也可以获得对应的dom节点
占用用户的cpu,其实现在用户的cpu最少都是1.5GHz以上,这点小运算对CPU来说根本就是骆驼身上的一个细胞,而且用户的cpu闲着也是闲着,既然对他供着电,那就让他做点事情吧.
当你对面向对象, 面向类 的思想和方法有着深刻的认识和理解后 , 你自己都能设计/写类库了, 那么你使用别人的类就很容易了. 而且, 不同的人, 写的同一个功能的类, 由于设计的水平/习惯/方式不同, 里面的构造函数,调用函数, 传参等的 方式, 传递参数的时期 也很可能不一样. 这就决定了你使用它的类的时候, 的写法也就不一样.
- get_client_ip是一个common/fucntions.php中的全局函数, 实际上是一种封装, 对$_SERVER服务器的信息来的.
- 上面的只是一个ip, 而要根据ip得到用户的实际地理位置, 就要通过 IpLocation这个类来写.
要注意, 每个网站都会 在客户端写 相应的 cookies, 那怎样区分呢? 难道只能保存一个站点的 cookie吗? :: 不是的, 实际上, 每个网站都可以在客户端写自己的cookie. 是分别放在不同的文件夹/或同一个文件中的. 区分不同的网站的 cookie, 以及网页页面 读取 和 载入 上传自己的 cookie , 这些工作, 是由 浏览器 自己来实现的, 由浏览器自己来 区分的! 浏览器自己会去查找和区分的!
php类的问题
- 虽然php的私有数据, 可以通过__set, __get来 动态设置和 获取, 但是不管从书写多少还是从执行效率来说, 都应该用 __construct构造函数在 初始化创建对象的时候, 传入自定义的配置参数(或数组) 这样更符合c/c++的写法.
public function __set($name, $value) {
if(isset($this->name)){
$this->name = $value;
} elseif (isset($this->cfg[$name])){
$this->cfg[$name] = $value;
}
}
public function __get($name){
return isset($this->name)?$this->name:$this->cfg[$name]; // 这些数组中的 下标变量 都不 要 加 引号!
}
私有成员的 定义 方式有两种, 一种是 单独的, 一个一个的 分离起来 写的; 另一种是 合起来 放在 配置 数组 成员变量中的. 两种方式都可以, 看你的 类操作数据 的 需求和方式来定. ** 要注意的是, 这两种方式, 在 引用上 的写法 是一样: 都可以用 $this -> memberName来 引用, 后一种数组方式, 也不必用: $this -> config['memberName') 来引用: 因为 你写的 __get($name) 就是配置数组中的成员 : {return $this->config('memberName'); **
php的 && 和 || : 不仅仅只是在 if条件判断中使用, 还有 更简洁的 使用方式: 直接 在 执行语句中写. 比如:
$this->reset && session($key, null);
比如:
<?php
namespace Common\General;
class Car {
protected
}
<?php
return array(
//'配置项'=>'配置值'
'AUTOLOAD_NAMESPACE' => array(
'General' => COMMON_PATH.'General',
),
);
在php中类的成员变量, 叫做: private/protected?public property(财产/属性), 只要你写了 __get魔术方法, 即使没有任何函数体语句, 那么你访问private/protected变量都不会出错. 因为实际上经过了这个魔术方法的处理了
Nerdtree的 关闭快捷键: 不是c, 而是x, 为什么是x? 可能是 根据 "通常 /所有的 窗口的 关闭 按钮上都是 写的: x " 这个习惯来的. 小写的x, 表示 关闭当前目录 折叠 到父目录. 那么 相反的 字母 X就是 关闭 当前目录下的 所有 已经打开的子目录
很重要的一个要点是: 对于数组元素, 索引名称 通常是用字符串 来表示, 但是 ,如果 索引名称 用 变量来表示的话, 由于 变量本来就已经 是 一个字符串了, 所以, 这时候, 数组引用的 时候, 就不要/不能 再在 变量的两边 加 任何引号了, 这时候, 如果加上引号, 反而会出错, 只有 在 echo的 时候, 才需要 在 变量 的两边加 单/双 引号.
if(isset($this->config[$name])){
$this->config[$name] = $value;
}
要排除tp中的验证码的错误, 就要对Verify类的源码进行分析
- 在 "绘制" 验证码的时候, 是一个字符一个字符 来进行绘制的, 所以, 生成的$code 就是一个数组. $code=array();
- 那么对验证码 进行加密的时候, 就要先把 数组 转换为字符串, 所以 用了 implode('', $code);
- tp的验证码,是不区分大小写的, 原因就只有一个, 在 调用 类的加密验证码方法 authcode 的时候, 先对字符串进行了 大写转换, 然后检查的时候, 调用check 方法的时候, 也对 传入的字符串参数进行了 大写转换的.
$code = $this -> authcode(strtoupper(implode('', $code)));
- 在authcode中 要注意区分几个概念和变量名称(自己就这么约定)
$key是 $_SESSION (这里是一个二维数组, 因为可能有多个验证码) 每个验证码的 名称索引;
$secode 是 $_SESSION的 每个索引 所对应的 验证码信息, 它也是一个数组, 包括两个元素: 元素的索引名称分别是: verify_code, verify_time
$code 则是每个$secode中的 verify_code对应的元素值了.
而 $key 和 $code 都是 由
$this -> authcode($code)
加密 而来的.因此, $_SESSION 的样子大概就是这样的了:
$_SESSION = array(
$key1 => $secode1,
$key2 => $secode2,
.....
);
其中 $key1 是由 $key 和 验证码的id组合而成的, 即: $key .$id
$secode1 = array ('verify_code' => $code, 'verify_time' => NOW_TIME);
authcode 是怎样进行加密的?
/* 加密验证码 */
private function authcode($str){
$key = substr(md5($this->seKey), 5, 8);
$str = substr(md5($str), 8, 10);
return md5($key . $str);
}
实际上,进行 了三次 md5的加密
里面有两个变量名称, 一个是 seKey : 称为"加密密钥"(这个是 类Verify的数据成员 ), 这个最好是 自己改一下, 不要用 tp的默认值; 第二个是 authcode的参数 $str, 称为"被加密字符串".
三次md5: 第一次 对 加密密钥$this->seKey 应用md5加密(这个是固定不变的, 不管你传递 什么 $str 都不变); 第二次 是对 "被加密字符串" $str 应用 md5; 第三次 是 对 前两次加密结果 连接起来的 结果 再进行一次md5 处理.
实际上, 上面的 验证码生成后, 写入到$_SESSION 中, 其中的 每个验证码的 索引名称 也是 用 authcode 加密得到的: 以类的 成员变量 seKey这个加密密钥 作为 被加密字符串 传递到 authcode方法后生成的 结果 + 加上 验证码的id 号
// 保存验证码
$key = $this->authcode($this->seKey);
$code = $this->authcode(strtoupper(implode('', $code)));
$secode = array();
$secode['verify_code'] = $code; // 把校验码保存到session
$secode['verify_time'] = NOW_TIME; // 验证码创建时间
session($key.$id, $secode);
关于tp的verify的 check函数?
$id 参数的默认值 等于空, 因为在 生成entry 和 验证的时候, 都是设置的 空
// 要去获取 $_SESSION 中的验证码, 首先要获得索引名称, -> // 要去获取 $_SESSION 中的验证码, 首先要获得索引名称 , 然后判断: (这里只判断了3 种情形, 但是也有可能有其他情形没有被包含, 所以要 默认的 返回false)
第一种情形, 如果是 传入的字符串为空, 或 $_session中的 验证码为空, 则false;
第二种情形, 如果验证码 过期: 用当前时间 - 验证码的生成时间, 如果 大于 设置的 过期时间 (tp的默认过期时间是 1800s 半小时), 则false, 并且要删除当前这个 验证码. 注意 在tp的帮助文档中说了, 删除某个 session, 使用的是 session($name, null), 实际上这个 $name就是 session 的 索引名称.
第三种情形, 就是 验证成功. // 也是 对传入的参数 进行 大写转换后, 进行authcode 处理为md5 后进行比较的.
$this->reset && session($key, null) ;
的解释是:
public function check($code, $id = '') {
$key = $this->authcode($this->seKey).$id;
// 验证码不能为空
$secode = session($key);
// 第一种情形
if(empty($code) || empty($secode)) {
return false;
}
// session 过期
if(NOW_TIME - $secode['verify_time'] > $this->expire) {
session($key, null);
return false;
}
// 第三种情形
if($this->authcode(strtoupper($code)) == $secode['verify_code']) {
$this->reset && session($key, null);
return true;
}
// 默认没有提到的情形
return false;
}
tp框架中的一些疑点知识-8的更多相关文章
- tp框架中的一些疑点知识-7
mysqli是用面向对象的,所以用箭头对象语法, 而mysql是用C语言面向过程写的, 所以用的都是php全局函数 式的写法. tinkle: 叮叮当当的响; (口语)一次电话, i will giv ...
- tp框架中的一些疑点知识-5
关于vim中的缓存区的前后bp和bn的界定 通过命令ls可以看到 缓存区的 排序. 最开始打开的文件排在最上面, 序号最小. 那么它们就是 更 前 的缓冲区. 序号更前的用bp, 序号靠后的用bn. ...
- tp框架中的一些疑点知识-2
tp中有三种常量: 预定义常量, 这个设置后不会随环境的改变而改变的,比如'URL_MODEL' => 1 注意是 model, 不是 url_mode 路径常量, 也不会随环境的改变而改变的, ...
- tp框架中的一些疑点知识-3
rewrite就是伪静态, 伪静态就是 rewirte, 可以把入口地址隐藏掉. 兼容模式就是 普通模式 和 pathinfo模式的 结合, 前面是普通模式 ?s= , 后面的 模块/控制器/操作和参 ...
- tp框架中的一些疑点知识-6
vim自带一个目录浏览器,使用命令:E就可以调出来,实际上就是浏览器的名字就是"网络读写"netrw vim也自带了 补全功能, 启动键是 "ctrl_N" 或 ...
- tp框架中的一些疑点知识-4
$_SERVER的几个元素: script_name脚本名称, 是指这个脚本文件本身的文件名, 通常只是 : /index.php path_info: 是从控制器/操作方法开始到最后的内容,包括路径 ...
- tp框架中的一些疑点知识-1
tp默认的编码是utf-8 Runtime中的Cache和Logs都是分模块的,因为在应用app下可以有多个模块,但是 公共模块和Runtime模块只有一个, 所以, Runtime要包含各个模块的内 ...
- tp框架中的一些疑点知识--cookie和session的配置
不同的浏览器采用不同的方式保存Cookie. IE浏览器会在"C:\Documents and Settings\你的用户名\Cookies"文件夹下以文本文件形式保存,一个文本文 ...
- TP框架中关于if、else 分支结构逻辑错误
TP框架中关于if.else 分支结构逻辑错误 代码中没有任何错误 将注释往下一行就可以解决 造成问题的原因: TP框架中 想分配变量可以使用assign方法 在[模块]中: $this->as ...
随机推荐
- vue框架(三)_vue引入jquery、bootstrap
一.vue安装jquery 1.按照之前博客的内容,新建一个vue工程. 2.在项目文件夹下,使用命令npm install jquery --save-dev 引入jquery. 3.在build/ ...
- linux如何在不重新登录用户的情况下使用户加入的组生效
这个问题在很早之前就遇到了,之前的解决方法是登出用户再登录用户.今天在配置virtualbox的过程中又遇到了同样的问题.于是又进行了一番搜索. 找到了如下答案: https://stackoverf ...
- caffe深度学习进行迭代的时候loss曲线开始震荡原因
1:训练的batch_size太小 1. 当数据量足够大的时候可以适当的减小batch_size,由于数据量太大,内存不够.但盲目减少会导致无法收敛,batch_size=1时为在线学习. ...
- Python全栈-day12-day13-函数4
1.迭代器 1)定义:迭代取值的工具 2)优缺点 优点 a.提供一种不依赖索引取值的方法 b.同时一时刻内存在存在的值只有一个,更加省内存 缺点 a.取值麻烦,只能通过next方法一个一个地往后取 b ...
- 08 集合[11,22,33,44,55,66,77,88,99],将所有<66的值保存至字典的第一个key中,将所有>=66的值保存至字典的第二个key中。即:{'k1':<66的所有值,'k2':>=66的所有值}
li = [11,22,33,44,55,66,77,88,99]dict = {'k1':[],'k2':[]}for i in li: if i < 66: dict[& ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列1-基本概念和架构
前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型 ...
- Nginx技术研究系列3-OpenResty安装配置
上两篇中介绍了: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 Ngnix技术研究系列2-基于Redis实现动态路由 发现,应该加一篇OpenResty的安装部署说明,方便大家按图索骥 ...
- Linux基础命令---init进程
init init是所有进程的父进程,它由内核执行,可以启动其他所有的进程.init指令在启动时会参考/etc/inittab文件的配置,完成其他进程的启动.init通常不会由用户进程执行,并且期望进 ...
- vue-i18n国际化插件
vue-i18n国际化插件 安装,到项目目录下执行:npm install vue-i18n 配置在src\main.js里面引入vue-i18n // 语言包插件import VueI18n fro ...
- centos-ftp搭建
参照https://blog.csdn.net/a735834365/article/details/80622105 https://blog.csdn.net/a735834365/article ...