tp剩余未验证内容-2

时间:2022-04-20 04:56:15

如何设置一个 "资源" (文件/图片/zip/视频等)在点击时, 自动开始下载?

通常只要在这些地方, 设置 一个链接a, 让href等于这个资源就行了. 这样当点击这个资源时, 由于浏览器并不能直接打开这些exe, zip等文件,所以会弹出下载对话框. 当然这个跟你的浏览器的设置/功能/插件等有关系.

比如:<a href="foo.bar.zip" title="点击下载"> 下载 </a>

关于文件的upload?

  1. 分清楚两个数组, 第一个数组是, 设置上传参数的数组. 另一个是 获取上传文件的信息数组. 主要是第一个数组, 因为第一个数组是设置的,你可以修改和控制的, 而第二个数组, 你只是被动的获取信息, 你对它是无能为力的, 你不能对它进行修改什么的.

  2. 上传文件的名称分为两个部分, saveName是保持的文件名(不包括扩展名), 而saveExt才是设置的扩展名, 通常扩展名是不需要修改的,不用管的.

  3. 上传文件的保存路径是个重要问题, 包括: rootPath, savePath, autoSub, subName, 最后的真实存放路径是 三个相加 即: rootPath/savePath/subName / 文件名 通常rootPath(如果不设置的话)就是站点的根"/", 而savePath也可以设置多个子目录的, 比如: `savePath="./Public/Uploads/"

  4. maxSize是上传文件的允许最大值, 通常我们只允许上传 图片, 而且是jpg|png|gif等, 所以上传最大值设为5M就完全足够了,当然如果你要上传的是压缩文件,做下载 网站的话, 那是另外的事了.

默认的使用的是 Local类(upload的默认 驱动类)

namespace Think\Upload\Driver;
class Local{

一个请求 包括: 请求头 + 请求体

请求头包括: 请求方法(get/post) 站点名称/比如www.foo.com 使用的http协议版本 比如: http1.1

请求体: get方法的请求内容被放在请求头中, 所以 get的请求体为空; post的请求体 根get的请求内容类似 也是由 key=value组成的 用& 连接的字符串.

enctype: 表示 表单在将数据发送到服务器之前, 需要对发送到服务器的内容进行编码. 根据表单 中的控件的类型和 传递数据的不同, 有三种编码: 一是 text/plain 纯文本式的编码, 只是将空格转换为 加号+; 二是 application/x-www-form-urlencoded: application/x表示是非标准的mime, urlencoded表示将要传递的数据 进行 url数据编码. 即我们常见的 传递 username, password captcha等内容的表单所用的编码. 普通的post/get就是用的这种编码; 三是, multipart/form-data表示的是将数据进行二进制编码, 可以传递二进制内容, 比如exe/rar文件, 图片, 音频/视频等内容.(实际上, 此时的Content-type就是 multipart/form-data了) 所以 凡是要上传文件的 form 都应该设置 enctype为 ...

input的file域 ,就是由 两个部分组成的, 一个是前面的 文本域, 另一个是后面的 browse... 按钮. 即这两部分加起来, 才是一个 文件域.


Tp的 upload类, 需要 上传驱动, 默认的驱动叫 local. 这个Local 并不是 凭空想象的, 而是真实存在的一个 类. 它在 \Think\Upload\Driver 目录中,叫 class Local{...}

其中, 正是在 这个Local类中, 有 方法 checkRootPath($rootpath) , 和 checkSavePath($savepath). 正是在 checkRootPath中, 判断了

public function checkRootPath($rootpath){
if(!(is_dir($rootpath)&&is_writable($rootPath))) {
$this->error = '上传根目录不存在, 请尝试手动创建'.$rootpath;
return false;
}
$this->rootPath = $rootpath;
return true; }

从上面的代码可以看出, 如果$rootpath不是一个目录(即 真的不存在), 或者, 即使$rootpath是一个目录, 但是 如果它不可写, 都会报错: '上传根目录不存在, 请尝试手动创建'.$rootpath

所以 这里的 报错提示 其实也不是非常恰当, 容易让人产生误解: 比如我明明已经创建了上传目录, 上传目录已经存在, 你还包上传根目录不存在, 就让人有些困惑了, 此时你可以提示: 目录不可写. 或者你分两次 if(!is_dir($rootpath)) { 目录不存在... ;} elseif(!is_writable($rootpath){ ...目录不可写...} 来提示 错误信息, 也可以, 也更好.

upload类本身在 $config 配置中, 做了一些 预先的设置/设定, 比如 'rootPath' => './Uploads', 'savePath' => '', 'saveName' => array('uniqid', '');所以, 除非你不需要对上传文件做进一步处理, 否则, 通常,都应该 "显式地对这些配置 做设置说明"

upload是怎样 实例化上传类对象 private $this->uploader 的?

  • 是在 upload类的 构造函数中, public function __construct($config, $driver, $driverconfig)中, 调用 了类的private 方法setDriver().
  • 在setDriver中 首先获得 $driver, $driverConfig字符串, 然后获得 $class驱动名称, 然后 创建对象: $this->uploader = new $class($config);
  • 其中 $driver和 $driverconfig是通过 ?: C('FILE_UPLOAD_TYPE') 来获得的, 如果没有显式地传递 上传驱动名称, 比如 ftp等, 就从convention.php中的配置中获得, 而 C('FILE_UPLOAD_TYPE')的配置 正好就是 "Local" 所以默认的就是使用的 \Think\Upload\Driver中的Local.class.php 类文件驱动.

### tp框架, 以及php 以及包括js编程, 都是 一个重要的思想就是, 将 "不变" 和 "变", "字符串常量"和变量, 要创造性 的结合起来, 组合起来, 即: 凡是在 **对(只能是)变量赋值的地方** , 比如 $savePath, $this->savePath, 或 $config = array(....)中, 都可以用 ='/Uploads/'. $category 的方式来赋值 这样 savePath就可以根据不同情况而改变了.


关于在tp框架中上传文件的大小限制, 实际上, 是多重限制了.

除了tp的上传类 Upload类中的设置: $this->maxSize(这个是以字节为单位进行计算), 还 需要 设置php 语言本身 对上传文件大小的限制(默认只有 2M) . 这个是在php的配置文件

php.ini中设置 upload_max_filesize:

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 0 (设为0就是不限制大小)

关于upload上传的问题?

  • 上传文件在服务器上的名字显示中文乱码?

  • 上传文件时 $file或$_FILES中生成的md5 码和 sha1 有什么作用?

    md5, sha1, crc32这三种校验码的特点是: 对于一个文件, 如果文件的内容没有做修改,那么即使他的文件名改变, 则他的校验码不变; 反之, 如果文件的内容作了修改, 即使文件的名称不变, 则他的校验码也不同. 所以有几种用途:

    一是, 网站贴出(上传)文件的md5 sha1码, 你可以跟你在本地的文件的md5校验码相对比, 如果相同, 则表明文件是完整的,没有做修改, 反之,如果不同, 则说明被作了手脚的. 同样的, 你从网上下载的应用程序, 原程序的校验码md5的作用也跟这个相同;

  • 二是 "网盘"的 极速上传. 实际上是先计算出你上传文件的md5, 然后跟网盘的 md5库进行比对, 看md5库里有没有 你要上传文件的md5. 如果有,就不必再上传了, 只是在你的 网盘空间 生成一个 文件链接就好了, 链接 到库文件. 这样既节省带宽, 又节省 服务器的 空间.

怎样获取数组的长度?

  • 不能用点号或-> 来获取, 前者会把数组和后面的内容当作一个 字符串来 连接输出; -> 会把前面当作一个对象来输出, 会报错: array不是一个0bj , 所以 也就是说, php中的 对象只能用 -> 来输出, 不能 用点号了 因为点号被用作字符串连接运算了

  • 也不能使用 中括号 [], 那是求数组元素的值

  • 应该用 php提供的全局函数 : count 或 sizeof. (sizeof是count的别名alias, 一样的) 但是 count 在计算 二维数组的时候, 有第二个参数 [COUNT_RECURSIVE]这个常数. 如果为0

(默认)的不递归计算, 为1 则递归计算. 基本上 为1 的是用不上的.

  • count还可以计算对象的 属性的 个数.

为什么设置了 upload_max_filesize后, 仍然不能上传大文件? 对上传的临时目录也不能少, 而且要有 php进程所有者有写入的权限 . php脚本运行到底有哪些限制? 参考:

https://blog.csdn.net/dreamboycx/article/details/9171781, https://blog.csdn.net/steven_liwen/article/details/51965954 http://www.phpernote.com/php-function/789.html

  • 原因, 在上传大文件的时候, 不只是对上传文件本身的大小 要设置, 还有就是 php语言为了安全, 对脚本运行的本身 多项配置做了限制. 比如 一个脚本执行的最大时间, 你不能过长了, max_execution_time, 默认的是30秒, 通常你可以设置为 600(秒)
  • 本身限制了一个脚本占用内存的大小, memory_limit 默认是128M, 通常你可以设置为200M
  • 本身在 表单上传时 也做了限定, 包括 post_max_size表单上传时一次可以post的最多内容(默认是8M, 你通常可以设置为200M) ; max_input_time 即input接收文件输入的最大时间, 默认是60s, 通常你可以设置为 600秒.
  • 除了这四个设置外, 基本上就没有问题了, 另外的 file_uploads要设置为0n, 还有就是上面的upload_tmp_dir目录 必须要设置, 且要有写入权限. (当然你在上传表单的时候, 还是应该给用户/读者一些 提示说明, 告诉 用户可以上传文件的最大尺寸; 以及其他一些说明项目,比如只能传递图片, 就要设置: $config = array(...., 'exts' => '.jpg, .png, .gif, .jpeg' 等)

fedora安装 chrome浏览器

共有5个版本, 依次是: chromium 金丝雀 Dev Beta Stable 稳定版. chromium是每隔几个小时就有新的版本出现...


被上传的文件 最后, 在盘上的实际存储目录是: savepath = 设置的savePath + subName/ (不包括rootPath). 有这样的代码:

$file['savepath'] = $this->savePath . $subpath;

上传文件的类型'type' => string 'application/octet-stream' 表示是 8进制数据流(也就是二进制流)

'application/x-msdownload' 表示是windows的dll, exe等文件的mime类型

判断一个函数是php的全局函数, 还是类的成员函数, 其实很容易, 如果 前面有 $this-> 来引用函数, 说明是类的成员函数, 否则就是全局函数,比如Upload中的 md5_file, $file['tmp_name']) sha1_file两个函数

Tp的Upload类, 主要也是对php原生的 上传相关函数 作了一些调用和封装,

**关于文件名, 有几次变换: name(原来本身的名称) -> tmp_name(上传后保存在 upload_tmp_dir/ 目录中的临时名称, 由系统自动生成) -> saveName(最终保存在服务器上的名称)

**比如:

function upload($files){
// 通常都不会设置upload函数的参数: 上传文件数组, 因此 $files==='', 所以, 这里的$files 就是 $_FILES; // 后面是对每个文件进行遍历:
foreach($files as $key => $file) // 获取上传文件的md5: md5_file, sha1_file($file['tmp_name']...
// 要注意 , 获取文件的md5_file中的文件参数, 必须是 "绝对路径", 而且是从 点号开始的 绝对路径 :
// $fn = './Honda/Home/Controller/deny.txt';
// if(is_file($fn)) echo '<p> 文件的md5是: '.md5_file($fn).'文件的sha1是: '. sha1_file($fn). '</p>'; }

在一个类中, 类的成员属性, 可以数组是 ,也可以包括: $config=array(...)性质的数组, 也可以是单独的/ 独立的 变量, $private_name private $error; private $uploader; 等等.

而且对一个类来说, 魔术方法 __get, __set , __isset几乎是必须的. __construct 和 函数getError(return $this->error;) 根据需要而定.

上传文件保存错误? 是因为 上传文件的类型不对? 在Local类的代码中???

Warning: POST Content-Length of 10926845 bytes exceeds(超出, 超过...界限) the limit of 8388608 bytes in Unknown on line 0表示的是, 在上传大文件的时候, post的传送数据量 超过了 post_max_size的设定值, 这个设定值是 8M

复选框和单选框的操作:

前端的复选框, 是将多个选项的名字 , 设置为 同一个数组, 这样, 赋值原理: ** 在后台$_POST的时候, 前端的多个选项值就会传到 $_POST的同一个名字的元素下, 从而形成一个二维数组, 这个二维数组的 有一个 元素, 索引名字为 前端的 name, 值就为你的选项, 即:**

$_POST = array('hb' => array('lq', 'zuq'....);

dump 出来就是:

array (size=1)
'hb' =>
array (size=3)
0 => string 'lanqiu' (length=6)
1 => string 'zuqiu' (length=5)
2 => string 'paiqiu' (length=6) hb: Array <p>
<label>选择的爱好:</label><br>
篮球 <input type="checkbox" name="hb[]" value='lanqiu' /><br>
足球 <input type="checkbox" name="hb[]" value='zuqiu' /><br>
排球 <input type="checkbox" name="hb[]" value='paiqiu' /><br>
</p> foreach ($_POST as $key => $val){
echo '<p>'.$key.": ". $val; // 的结果就是: hb: Array }
echo "你的爱好是: ". implode(',' $_POST['hb'])); 而raido的处理更简单, 后台根本就不用改, 一样取得到 , $_POST 就是一个普通 的一维数组
<label>选择的爱好:</label><br>
篮球 <input type="radio" name="hb" value='lanqiu' /><br> // 后台赋值的原理: 名字是一样的, 所以, 不管你选哪一个, 后面选择的, $_POST['hb'] 总是只有一个,
足球<input type="radio" name="hb" value='zuqiu' /><br> // 而且 后面的值总是会覆盖前面的值
排球 <input type="radio" name="hb" value='paiqiu' /><br>

通常在使用js bootstrap, jquery等的时候, 都是使用的压缩版的, 开发中的 min就是 压缩版的意思,比如 jqury.min.js, bootstrap.min.css, bootstrap.min.js

### 所谓框架, 就是今后在写 html前端和js和php后台的时候, 都不用/少用 原生的html东西了, 习惯于直接用bs,jquery,tp等给我们搭好的那一套了,这些框架都是人家反复使用, 反复论证,给你弄好了的, 就是适合最大多数的情况!

bs中的btn的用法:

  • 有 btn-mute(提示的) , btn-primary(主要的 或者说是基本的按钮), info(通知的), warning, danger, 以及default的.
  • 除了本身是button标签元素使用这些btn类, 其他任何dom元素, 只要使用这些btn类, 就会显示为 btn的样式. 只是 通常不会这么做, 通常还要考虑"语义"上的问题, 通常 会将 a链接 标签应用为 btn 样式.

bs主要是/只是 修改了/定义了css的类, 并不会去修改html标签元素 的 类型type , 原来是什么type, 还是什么类型,并没有改变. 所以, 即使是 button标签, 你定义了class="btn btn-primary", 但还是要 显式的写上 type="button"

bs中大量的使用了data-自定义属性?

  • 这些data-属性通常是使用在 div上的. div用上bs的类后, 通常就不再是div了
  • data-toggle, 表示的是div 的内容 以"什么事件触发"? 即表现为 什么 形式/外观? 比如: data-toggle="modal"/popover, 或 tooltip等
  • data-target表示的是事件的目标, 表示 数据 的来源???

bs中为什么使用了btn-primary样式外 还要写 btn?

  • 是因为这两个class样式, 实际上定义的css是不同的, 不重复的.
  • 如同 写原生的css的时候, 要将多个样式中,大量重复的内容 提取出来, 写成单独的一个样式一样, bs的按钮也是这样, btn样式是 "基础样式" 的代码, 其他 "btn-primary" "btn-warning"等样式只是 额外的, 不同的样式那部分内容. 这样做的 好处是: 实现"基础样式"和 "附加样式"在代码上的分离.
  • 比如: btn样式就规定了很多的css样式:
.... display: inline-block;
padding: 6px 12px;
font-size: 14px;
font-weight: normal; line-height:...

link表示链接, 通常引入css文件的时候, 只写 rel="stylesheet"就行了,不必写type

html 原生button和input-button的区别?

本身 html中确实是有 button 这个 标签元素的!

  • 它是一个 非闭合标签 , 要和 <button>...</button> 配合使用, 而input type=button 是一个闭合标签
  • button标签的功能更多, 因为是非闭合标签, 所以 在标签之间可以放任何东西, 比如文本,比如img等都是可以的, 而input-button就只能是设置其value值
  • button如果放在form表单中, 不同的浏览器对它的作用解释的不一样, 比如ie认为它是一个 带有 submit 功能的提交按钮; 而 其他非ie 的浏览器比如firefox等认为它就是一个普通的按钮, 所以 如果要使用 button标签 的话, 在任何时候, 都应该显式地指定其 type: <button type="button"> (注意type=button并不多余! )... </button>
  • 表单的input type=button 的功能就要简单得多, 就只是一个 btn. 按钮而已没有其他什么附加的作用. 所以 如果你只是 想在form表单中 生成一个按钮的话, 最好还是用 input type=button.

表单的input 有很多种输入类型, 各自的作用要 弄清,比如 : input type="image" 则它并不单纯的是一个image, (如果单纯的img使用 <img>标签就好了, 干嘛还用input-image?) 而是一个 带有 submit功能的 以图片形式的 submit按钮




jquery和js的事件冒泡: 在 mouseover和 mouseenter上的区别, 根据两者的 字面意思上就可以区分: over是悬停,可以 不必直接进入, 所以mouseover 无论鼠标指针穿过 被选元素还是 其子元素, 都会触发mouseover事件. 而mouseenter事件是只有在鼠标指针真的穿入 被选元素时才触发.

linux中的 LSB是什么?

  • lSb lease significant bit 最低有效位, MSB最高有效位, 比如0x12345678, 16位的lsb就是: 0x5678
  • 但是 linux中的lsb是 linux standard base标准基础. 就是规定一系列二进制的基础架构和接口的.
  • 安装某些软件的时候, 需要 lsb的版本满足一定要求, 比如: lsb>=4.0(所以, 如果要用新的软件的话, 可能就系统的 很多组件 的版本就 不符号要求了)
  • 安装 lsb: dnf install redhat-lsb. 就可以提供命令: lsb_releas -a.... 或者查看lsb的配置文件: cat /etc/reahat_lsb

在数据库的模型类实例化时,

  • 使用M(); 表示使用 空模型类, 进行原生sql语句;
  • 使用 M('User'); 表示使用标准的 UserModel模型类(没有其他扩展方法和自定义属性), 操作对应的User表;
  • 如何 D('User'); 表示使用自定义的 模型类,其中的D表示 数据库database, datatable表等的意思.

可以使用 firefox 的命令行 来设置ff为默认的浏览器: firefox --setDefaultBrowser.

很多时候, profie也被翻译成 配置 的意思? config, settings, profile

https://www.zhihu.com/question/39827177一套既成的可迁移的实现特定目的的Configuration叫做Profile,例如手机里的静音Profile、仅震动Profile。Profile这个词很不好翻,本意是指一系列对特定个体的不一定全面的描述,翻成轮廓更准确但显然不符合习惯,所以常见翻译是档案。但是又显然,说静音档案、仅震动档案之类的也很不符合习惯,所以实际使用中Profile的翻译跟着场景变化很大。例如蓝牙的各种应用模式原文就是Profile,A2DP Profile什么的,但翻译成了模式.