-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.json
1 lines (1 loc) · 136 KB
/
search.json
1
[{"title":"年少不听李宗盛 听懂已是不惑年","url":"http://mrzhouxiaofei.com/2018/02/03/年少不听李宗盛 听懂已是不惑年/","content":"<p><img src=\"/images/年少不听李宗盛_1.jpg\" alt=\"\"></p>\n<p>2008 年,李宗盛 50 岁。50 岁是个标志性的年龄,人生开始转暗,你不得不跟很多事情妥协,身体、老去、时代的发展。都说,年少不听李宗盛,听懂的时候,你也成了有故事的人。</p>\n<p>2006 年 5 月,李宗盛启动了《理性与感性作品音乐会》个人演唱会。没有绚丽的舞台,华丽的服装,只有真诚的歌声,周华健、张艾嘉、张信哲、梁静茹等纷纷助阵。他曾经说过一句狂话:不管你给我什么乱七八糟的人,给我什么歌手,只要到我李宗盛手上,我就会让他红!这是一句实话。</p>\n<p><img src=\"/images/年少不听李宗盛_2.jpg\" alt=\"\"></p>\n<p>在那个时代,李宗盛的好友赵传歌唱得很好,但因为样貌原因一直不被关注。于是,李宗盛为他量身创作了《我是一只小小鸟》、《我很丑,可是我很温柔》,两首歌写尽了那些平凡男性的心酸。赵传说,这两首歌自己唱的时候真的像发泄一样,完完全全说的心中事。虽然歌曲灵感来自赵传,但这些歌其实是写给那些富裕起来的,已经买得起车的中产阶级听的。</p>\n<p><img src=\"/images/年少不听李宗盛_3.jpg\" alt=\"\"></p>\n<p>天后梁静茹,最初只是个来自马来西亚的乡下妹,一个爱唱歌的小姑娘。在一次歌唱比赛中,她和同学组合拿了第三名,而当时只是和声。这场比赛被收录在滚石马来西亚分公司的一张 CD 中。后来李宗盛去马来西亚分公司选材,从堆积如山的 CD 中挑中了这张。</p>\n<p>当时主管推荐的是这个组合的主唱,但是李宗盛一摆手,说:不,让那个和声的姑娘来。</p>\n<p><img src=\"/images/年少不听李宗盛_4.jpg\" alt=\"\"></p>\n<p>就这样的一句话,在茫茫的 CD 中,小姑娘梁静茹被大哥挑出来。她进了滚石,被李宗盛认作干女儿。李宗盛为这块璞玉,连续制作了《一夜长大》、《勇气》和《美丽人生》三张专辑,把她送进天后的行列。在《理性与感性音乐会》上,梁静茹挑起大梁,《不必在乎我是谁》、《诱惑的街》、《为你我受冷风吹》,李宗盛说 Sandy 的每一首歌都不好唱,辛苦静茹了。梁静茹说,老豆在旁边看着,我压力好大呀,只能好好唱。</p>\n<p>一代歌后陈淑桦,李宗盛曾说:她是最会唱歌的人。《梦醒时分》、《滚滚红尘》、《问》、《笑红尘》都出自她的口,与李宗盛合作过专辑《女人心》,成为了李宗盛的知己。</p>\n<p>2006 年,李宗盛要开理性与感性音乐会的消息传出,歌手纷纷报名,张艾嘉、周华健、梁静茹、张信哲,甚至成龙都抢着要来当嘉宾。但李宗盛最想邀请的,是他的红颜知己陈淑桦。而当时的陈淑桦,正因深爱的母亲去世而患上自闭症,拒绝与外界的一切联络。</p>\n<p>面对这样的好友,李宗盛内心溢满伤痛,用尽一切办法鼓励她振作。演唱会上,梁静茹唱了陈淑桦的代表作《梦醒时分》,鞠躬退场,大荧幕上出现李宗盛写给陈淑桦的信:</p>\n<blockquote>\n<p>淑桦,一切还好吗<br>但愿你已从失去母亲的深切哀伤里平复过来<br>不管我们乐不乐意<br>随着岁月增长<br>我们都得渐渐的去看见<br>人生更完整的面貌<br>我们所有的获得或失去<br>恐怕都不是生命的本意<br>反而是经历一切之后<br>从而发现自己</p>\n<p>这些年少有机会见你<br>在办公室碰见也只是擦身而过匆匆来去<br>记得小小黑黑的臭臭的录音室吧<br>对,我还在那里<br>记得不厌其烦<br>一再要你重来的小李吧<br>是的,我还是坚持<br>我要的自有道理<br>我仍然在为每一首歌<br>每一个艺人<br>每一个案子尽力<br>在绚烂舞台,惑人声名之外<br>尽力完成自己</p>\n<p>好久不见,淑桦<br>你在台下看吗<br>看小李变成真正的老李拉<br>头发没了,胡子白了<br>人漂泊了,心沧桑了<br>却依然要大声唱歌<br>好像当年一样<br>没关系的<br>日子会顺顺的往下去的<br>我们会再见面,唱歌<br>就像当年一样</p>\n</blockquote>\n<p>然而一代歌后还是不能走出母亲去世的伤痛,再未重现江湖,在台北过着平静平凡人的生活。</p>\n<p><img src=\"/images/年少不听李宗盛_5.jpg\" alt=\"\"></p>\n<p>李宗盛最懂女人心,不然也写不出这么多情歌。林忆莲亲身体会说:李宗盛是个很可怕的人,好像能看穿所有女人的心事。那时,辛晓琪与相恋 11 年的男友结婚后又分手,正遭遇人生中最为痛苦的时期。</p>\n<p>李宗盛写了《领悟》,给辛晓琪唱。</p>\n<blockquote>\n<p>我以为我会哭<br>但是我没有<br>我只是怔怔望着你的脚步<br>给你我最后的祝福<br>这何尝不是一种领悟<br>让我把自己看清楚<br>虽然那无爱的痛苦<br>将日日夜夜<br>在我灵魂最深处<br>…</p>\n</blockquote>\n<p>其实这也是小李写给自己的歌。</p>\n<p>50 岁以后,李宗盛的作品不再量产化,制作的事情也很少管,基本上处于半隐退状态。李宗盛自己说:即使是情歌,它都关乎那个年代的人的喜怒哀乐。</p>\n<p>他的第一张专辑《生命中的精灵》,那时李宗盛 27 岁,这个多愁善感的年轻人从三藩市飞东京成田机场转机回家,哭了一路,就这样为了姑娘的一个眼神,写了一张专辑。</p>\n<p>这是李宗盛第一张专辑,也是很多人最喜欢的一张。专辑里的小李,有着高亢的甚至是带点憨气的声音,还稍显稚嫩的念白式唱腔,年轻人陷入恋爱的热情纯真,这样的歌声,是后来有了很多故事的李再也无法重现的了。</p>\n<p><img src=\"/images/年少不听李宗盛_6.jpg\" alt=\"\"></p>\n<p>原文链接:<a href=\"http://oldjimpacific.blogspot.co.uk/2017/01/blog-post_13.html\" target=\"_blank\" rel=\"external\">年少不听李宗盛,听懂已是不惑年</a><br><br><br></p>\n","categories":["随笔"],"tags":["随笔"]},{"title":"CentOS 7 下解决服务器报 Redis server went away 的错误","url":"http://mrzhouxiaofei.com/2018/01/28/CentOS 7 下解决服务器报 Redis server went away 的错误/","content":"<p>这两天在学习 Redis,因为 Redis 在 Windows 上的表现并不好,而且线上环境基本上都是 Linux,所以选择在 CentOS 7 上跑跑例子。在安装完 Redis 的 PHP 客户端 phpredis ,测试连接时,碰到这个问题,特此记录。</p>\n<h1 id=\"问题\"><a href=\"#问题\" class=\"headerlink\" title=\"问题\"></a>问题</h1><p>开始在 Redis 上使用 redis-cli 跟着敲命令还没出现问题,后来需要使用 Redis 的 PHP 客户端 phpredis,在测试连接时,出现了问题。</p>\n<p>phpredis 是作为 PHP 的模块安装的,安装完以后,可以在 phpinfo 里看到,模块已经加载成功。</p>\n<p><img src=\"/images/phpredis_1.jpg\" alt=\"\"></p>\n<p>打开 redis-server 服务,通过浏览器,使用下面的代码测试连接 Redis 时,死活连不上,打开 F12,点击 Network,报 500。</p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><?php</span></div><div class=\"line\"> <span class=\"comment\">// 连接本地的 Redis 服务</span></div><div class=\"line\"> $redis = <span class=\"keyword\">new</span> Redis();</div><div class=\"line\"> $redis->connect(<span class=\"string\">'127.0.0.1'</span>, <span class=\"number\">6379</span>);</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"string\">\"Connection to server sucessfully,\"</span>;</div><div class=\"line\"> <span class=\"comment\">// 查看服务是否运行</span></div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"string\">\" Server is running: \"</span> . $redis->ping();</div><div class=\"line\"><span class=\"meta\">?></span></div></pre></td></tr></table></figure>\n<h1 id=\"解决\"><a href=\"#解决\" class=\"headerlink\" title=\"解决\"></a>解决</h1><h2 id=\"过程\"><a href=\"#过程\" class=\"headerlink\" title=\"过程\"></a>过程</h2><p>开始出现这个问题时,我最先想到是版本的问题,因为 PHP 是直接通过 yum 安装的,装完才发现是 5.4 的版本,比较老, 而 phpredis 是使用源码安装的最新版。猜测到可能是版本问题后,我把 PHP 5.4 及其所有的模块都卸载了,然后换源,安装上了 PHP 7.0,同时再次装上了 phpredis。通过浏览器访问测试代码时,依旧连不上,依旧 500,排除掉版本的问题,我已经不知道可能的原因了。</p>\n<p>说一下,我的电脑是 Windows + Ubuntu 的双系统,CentOS 7 是在 Windows 下通过 VMware 访问的。我想着在 Ubuntu 里试一下,重启,切换到 Ubuntu,装 phpredis,测试,直接就连接成功了。CentOS 7 里的问题没有解决,于是再次切换回来。</p>\n<p>不通过浏览器也能执行 PHP 文件,我试着在终端直接执行测试文件,也成功输出了</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">onnection to server sucessfully, Server is running: +PONG</div></pre></td></tr></table></figure>\n<p>直接执行可以输出,通过浏览器就不行,报的错误也是 500,基本能确定不是 PHP 和 phpredis 的问题,而是服务器的问题了。服务器的问题,可以查看日志,执行下面的命令可以查看服务器的错误日志。 </p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">cat /var/log/httpd/error_log</div></pre></td></tr></table></figure>\n<p>执行后可以看到,测试文件报了 Redis 的错误</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">PHP Fatal error: Uncaught RedisException: Redis server went away in...</div></pre></td></tr></table></figure>\n<p>有了报错,直接搜索报错信息即可。</p>\n<h2 id=\"方案\"><a href=\"#方案\" class=\"headerlink\" title=\"方案\"></a>方案</h2><p>网上给出的结果:SELinux 的访问控制导致了这个错误,可以通过改变 SELinux 的运行模式或者禁用 SElinux 解决。</p>\n<p>执行下面的命令,找到 SELinux 的配置文件</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">vim /etc/selinux/config</div></pre></td></tr></table></figure>\n<p>找到 SELINUX=enforcing 这一项,改为 SELINUX=disabled,如果还不行,执行下面的命令</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">/usr/sbin/setsebool httpd_can_network_connect=1</div></pre></td></tr></table></figure>\n<p>即可解决问题。</p>\n<h1 id=\"总结\"><a href=\"#总结\" class=\"headerlink\" title=\"总结\"></a>总结</h1><p>这次碰到的问题,不是一个大问题,但是却耽误了一些时间。SELinux 之前听到过,只是知道它是一个类似防火墙的东西,没有去深究,这次碰上了。准备看一下 SELinux,却在知乎上看到了 <a href=\"https://www.zhihu.com/question/20559538\" target=\"_blank\" rel=\"external\">Linux 下为何要关闭 SELinux?</a> 这个问题,我表示很气,不过还是打算了解一下。还有 Ubuntu 上为什么没出现这个问题,了解了一下,原来 CentOS、RedHat 等几个 Linux 发行版默认启用了 SELinux,而 Ubuntu 默认没有安装 SELinux。<br><br><br></p>\n","categories":["后端"],"tags":["Linux","PHP","环境搭建","Redis"]},{"title":"CentOS 7 下编译安装 Linux 4.14 内核","url":"http://mrzhouxiaofei.com/2018/01/22/CentOS 7 下编译安装 Linux 4.14 内核/","content":"<h1 id=\"编译之前\"><a href=\"#编译之前\" class=\"headerlink\" title=\"编译之前\"></a>编译之前</h1><h2 id=\"引入\"><a href=\"#引入\" class=\"headerlink\" title=\"引入\"></a>引入</h2><p>最近在学习 Linux,看到介绍内核,就想着自己编译一下内核,虽然不会搞硬件开发,不会写底层的东西,但还是想看一下编译的整个过程。想着就开始弄,没想到中间还是有很多坑的,尤其是编译之前,选择配置这一部分,配置项太多了,因为只是想看编译的整个过程,所以就没有深究每一个配置项。整个过程比较长,特此记录,避免以后再次踩坑。</p>\n<h2 id=\"环境\"><a href=\"#环境\" class=\"headerlink\" title=\"环境\"></a>环境</h2><p>开始之前,先介绍一下编译环境。直接在自己常用的 Linux 主机上编译,中间肯定会出现问题,最后可能导致系统崩溃,别不信,我已经吃过几次亏了,所以这次选择在虚拟机软件 VMware Workstation 上安装 Linux 虚拟机进行编译安装。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\">虚拟机软件:VMware Workstation 14 </div><div class=\"line\">Liunx 发行版:CentOS 7 内置内核 linux 3.10.0</div><div class=\"line\">待编译内核:linux 4.14.14</div></pre></td></tr></table></figure>\n<p>开始编译之前,先把几项准备工作完成。</p>\n<ol>\n<li><p>去 Linux 内核官网 <a href=\"https://www.kernel.org/\" target=\"_blank\" rel=\"external\">www.kernel.org</a> 下载 Linux 内核文件,选择稳定版(stable),文件名为 linux-4.14.14.tar.xz,去 CentOS 官网 <a href=\"https://www.centos.org/\" target=\"_blank\" rel=\"external\">www.centos.org</a> 下载最新的 CentOS 7。</p>\n</li>\n<li><p>把 CentOS 在 VMware 里装好,安装过程不在赘述,网上一大堆。这里提醒一句,分给 CentOS 的硬盘空间不要太小,不然内核编译之后,空间可能不够。我第一次编译时,就是因为分的太小了,<strong>/</strong> 目录装完系统之后只剩 6G 多,编译一个多小时,提示空间不足,编译失败,最后不得不重装系统,又耽误了时间。</p>\n</li>\n<li><p>此外,做好宿主机和虚拟机之间文件夹的共享,保证虚拟机可以读取宿主机里下载好的 Linux 内核文件,挂载可以实现,这个不会可以搜一下。</p>\n</li>\n</ol>\n<p>准备工作完成,下面正式开始编译内核,请做好踩坑的准备。</p>\n<h1 id=\"正文\"><a href=\"#正文\" class=\"headerlink\" title=\"正文\"></a>正文</h1><p>开始之前呢,还要啰嗦几句,我先把安装的大致过程说一下,避免做到某一步时,只是在重复,却不知道在做什么。</p>\n<p>编译安装大致分为以下几步:</p>\n<ol>\n<li>解压内核</li>\n<li>编译前,选择配置项,生成 config 文件</li>\n<li>编译内核</li>\n<li>安装模块,安装内核</li>\n<li>更新引导文件</li>\n</ol>\n<h2 id=\"解压内核\"><a href=\"#解压内核\" class=\"headerlink\" title=\"解压内核\"></a>解压内核</h2><p>先把内核文件放在上面提到的宿主机和虚拟机之间的共享文件夹,我的宿主机共享文件夹是 share,挂载到了 CentOS 的 /mnt/hgfs/share/ 目录下。</p>\n<p>切换到 root 权限,将内核文件解压到指定目录,这个目录是没有限定的,哪个都行,这里放到了 /usr/src/ 目录下,这个也是 CentOS 内核所在的目录,后缀 .tar.xz 的文件可以使用下面的命令解压。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">tar xvJf linux-4.14.14.tar.xz -C /usr/src/</div></pre></td></tr></table></figure>\n<p><img src=\"/images/内核编译_1.jpg\" alt=\"\"></p>\n<p>内核解压之后,每个文件夹内包含的是什么代码,可以自行搜索了解一下。</p>\n<h2 id=\"配置项\"><a href=\"#配置项\" class=\"headerlink\" title=\"配置项\"></a>配置项</h2><p>重点来了,解压之后,编译之前要先生成 config 配置文件。这个文件是干什么的呢?它是编译时的必备文件,指明了所有的配置项,编译时就是根据你选择的配置项来定制内核的。在你的 CentOS 内同样有这样一个配置文件,在 /boot/ 目录下有一个 config 开头的文件,就是它,你可以先 cat 一下,会发现都是键值对,所有的配置项都在这。</p>\n<p>配置项非常多,可以随心所欲的定制内核,把不需要的全部关闭,当然也不是随心所欲,某些配置项是必须要选的,否则可能连系统也启动不了。</p>\n<p>选择配置项的方式有以下几种,当然它们的目的都是为了生成 config 文件,所以选择哪种都可以。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div></pre></td><td class=\"code\"><pre><div class=\"line\">make config (基于文本的配置界面)</div><div class=\"line\">make menuconfig (基于文本菜单的配置界面)</div><div class=\"line\">make xconfig (基于图形窗口的配置界面)</div><div class=\"line\">make oldconfig (基于原来内核配置的基础上修改)</div></pre></td></tr></table></figure>\n<p>以上几种,make xconfig 最为友好,基于窗口操作,但是需要 Xwindow 的支持,CentOS 还好,若是使用其它没有图形界面的发行版就 GG 了。make menuconfig 相对比较友好,又是基于文本菜单,所有的发行版都可以使用,所以这里推荐使用 make menuconfig。</p>\n<p>使用 make menuconfig 需要 ncurses-devel 的支持,如果之前没装过,需要执行下面的命令安装一下。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">yum install ncurses-devel</div></pre></td></tr></table></figure>\n<p>执行 make menuconfig,开始选择配置项</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">make menuconfig</div></pre></td></tr></table></figure>\n<p><img src=\"/images/内核编译_2.jpg\" alt=\"\"></p>\n<p>如果执行没有错误的话,会出现下面这个页面</p>\n<p><img src=\"/images/内核编译_3.jpg\" alt=\"\"></p>\n<p>Linux 内核所有的配置项都在这里,我第一次看到时,我去,这也太多了吧,这什么时候能看完。</p>\n<p>为了选择配置项,又开始搜配置项的意思,看了几个比较大的之后,比如基本配置、网络、文件系统等等,就没再看了。我开始是为了看整个编译过程,研究每一配置项,没有太大的意义,并且不同的 CPU 架构,所能配置的配置项也是不一样的。网上有人解释了每个配置项的意义,可能不是最新的内核,感兴趣的可以研究一下 <a href=\"http://www.jinbuguo.com/kernel/longterm-linux-kernel-options.html\" target=\"_blank\" rel=\"external\">Linux 内核配置选项简介-金步国</a></p>\n<p>内核的编译分为两个部分,核心和模块,对于核心的部分,要编译进核心,可能以后会用到的部分,尽量编译成模块。</p>\n<p>文本菜单选择界面,使用左(←)、右(→)箭头切换底部菜单,上(↑)、下(↓)箭头切换中间的配置项,<strong>空格键</strong> 选择配置项,部分配置项右边有 <strong>—></strong> 标识,代表有下级子项,可以使用 <strong>Enter</strong> 进去选择。</p>\n<p>同时每一项的前面都有以下标识,可以根据需要选择。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><*>[*] 表示编译进核心</div><div class=\"line\"><M> 表示编译成模块</div><div class=\"line\">空格 表示不选中此项</div></pre></td></tr></table></figure>\n<p>当然,如果你只是看一下整个编译过程,不想深究每一项,执行上一步 make menuconfig 之后,直接保存退出就可以了,它会使用 CentOS 内部的配置文件作为这次编译的配置文件,不知道 CentOS 内部配置文件在哪的,自己往前翻。</p>\n<p>保存退出之后的效果如下图</p>\n<p><img src=\"/images/内核编译_4.jpg\" alt=\"\"></p>\n<h2 id=\"编译\"><a href=\"#编译\" class=\"headerlink\" title=\"编译\"></a>编译</h2><p>配置项选完,config 配置文件生成之后,就可以开始编译了,编译需要 elfutils-libelf-devel 的支持,先执行下面的命令安装一下。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">yum install elfutils-libelf-devel</div></pre></td></tr></table></figure>\n<p>内核的编译,执行 make 即可开始编译。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">make</div></pre></td></tr></table></figure>\n<p>若编译过程中提示 <em>致命错误:openssl/opensslv.h:没有那个文件或目录</em> ,请执行下面的命令安装一下依赖。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">yum install openssl-devel</div></pre></td></tr></table></figure>\n<p>编译时间比较长,如果上面你是自定义配置项,把不需要的配置都关闭,编译会快的多。我这使用的 CentOS 内部的配置文件,CentOS 为了大多数人的使用,开的配置项比较多,所以编译的时间比较长,当然,也和你的电脑配置有关。我记了一下时间,这一部分的编译用了两个半小时,所以请耐心等待,可以去喝个咖啡。</p>\n<h2 id=\"安装\"><a href=\"#安装\" class=\"headerlink\" title=\"安装\"></a>安装</h2><p>经过了漫长的等待,终于编译完成,现在可以开始安装了。上面配置项有的编译进核心,有的编译成模块,所以安装也分为两个部分,模块安装和核心安装。</p>\n<p>执行 make modules_install 开始安装模块</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">make modules_install</div></pre></td></tr></table></figure>\n<p>等待完成,执行 make install 开始安装核心</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">make install</div></pre></td></tr></table></figure>\n<p>执行完成之后,就可以在 /boot/ 目录下看到新编译的内核了。</p>\n<p><img src=\"/images/内核编译_5.jpg\" alt=\"\"></p>\n<h2 id=\"更新引导\"><a href=\"#更新引导\" class=\"headerlink\" title=\"更新引导\"></a>更新引导</h2><p>到现在为止,离成功就差一步更新引导了。可以直接去修改 /boot/grub2/grub.cfg 文件来更新引导,但是非常不建议这样去做。</p>\n<p>推荐使用 grub2-mkconfig 来更新引导文件,下面的命令会根据 /boot/ 目录下的内核文件自动更新 grub 文件。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">grub2-mkconfig -o /boot/grub2/grub.cfg</div></pre></td></tr></table></figure>\n<p><img src=\"/images/内核编译_6.jpg\" alt=\"\"></p>\n<p>执行完之后,下次启动系统的时候就可以选择我们编译的内核了。如果想修改默认的启动内核,可以通过修改 /etc/default/grub 文件来实现。</p>\n<p>重启系统,如果看到两个内核,说明已经成功了,你可以自由的选择哪个内核。</p>\n<p><img src=\"/images/内核编译_7.jpg\" alt=\"\"></p>\n<p>至此,内核的编译安装就全部结束了,整个过程中,如果出现什么问题,根据报错信息就可以解决了。最后再啰嗦几句,说说这次编译。</p>\n<h1 id=\"总结\"><a href=\"#总结\" class=\"headerlink\" title=\"总结\"></a>总结</h1><p>用 Linux 系统也很久了,没去研究过内核,只是知道而已,就是突然心血来潮想要编译一下 Linux 内核,就去搞了,一个简单的编译,还是遇到了不少坑。首先,第一次编译时,CentOS 分区给的太小,导致内核编译了一个多小时后停了下来,一看,好嘛,空间已经用完了。马上删了虚拟机,又重装,这次分了 50G,应该不会出现这个问题了。选择配置项的时候,又研究了一上午,一直在看每个配置项什么意思,总是想把每一项弄明白,看了一部分后,感觉工作量太大了,而且背离了初衷,然后就不看了,直接跳过去了。后面的过程就比较快,一气呵成。比较不足的还是没有定义自己的配置项,把自己编译最大的好处隔过去了,以后需要了再去搞吧,编译应该能节省不少时间。来来回回整了两天,虽然东西不太多,我感觉还是有点意义的。<br><br><br></p>\n","categories":["后端"],"tags":["Linux","环境搭建"]},{"title":"计算机硬件概述","url":"http://mrzhouxiaofei.com/2018/01/20/计算机硬件概述/","content":"<p>作为一个计科软件方向的学生,计算机的硬件部分了解的不是太多,今天又看这一部分的内容,简单的做一个总结。</p>\n<h1 id=\"组成部分\"><a href=\"#组成部分\" class=\"headerlink\" title=\"组成部分\"></a>组成部分</h1><p>计算机的组成主要分为三部分</p>\n<p><strong>输入单元:</strong> 包括键盘、鼠标、扫描仪等;<br><strong>中央处理器(CPU):</strong> 含有算术逻辑、控制、记忆等单元;<br><strong>输出单元:</strong> 包括屏幕、打印机等。</p>\n<p>计算机通过主板将主要组成部分连接在一起,主板上面最重要的是芯片组,芯片组通常又分为两个桥接器来控制各组件的通信,分别是:<strong>北桥</strong> 负责连接速度较快的 CPU 、内存与显卡等组件;<strong>南桥</strong> 负责连接速度较慢的周边接口,包括硬盘、USB 、网卡等。</p>\n<h1 id=\"CPU\"><a href=\"#CPU\" class=\"headerlink\" title=\"CPU\"></a>CPU</h1><h2 id=\"概述\"><a href=\"#概述\" class=\"headerlink\" title=\"概述\"></a>概述</h2><p>中央处理器(CPU)是一个具有特定功能的芯片,里面含有微指令集。CPU 由两个部分构成,分别是算术逻辑单元和控制单元,CPU 计算所需要的数据从 <strong>内存</strong> 读取。</p>\n<h2 id=\"分类\"><a href=\"#分类\" class=\"headerlink\" title=\"分类\"></a>分类</h2><p>依据 CPU 内部的微指令集,可以把 CPU 分为两类,分别是 <strong>精简指令集(RISC)</strong> 和 <strong>复杂指令集(CISC)</strong>。目前使用范围最广的精简指令集 CPU 就是 ARM 了,几乎所有手机中的处理器都是 ARM 架构的。常见的复杂指令集 CPU 主要有 AMD、Intel 等 x86 架构的 CPU。</p>\n<h2 id=\"主频、外频与倍频\"><a href=\"#主频、外频与倍频\" class=\"headerlink\" title=\"主频、外频与倍频\"></a>主频、外频与倍频</h2><p><strong>主频:</strong> CPU 内核工作的时钟频率,我们经常说的指的就是主频;<br><strong>外频:</strong> 指的是 CPU 与外部组件进行数据传输/运算时的速度;<br><strong>倍频:</strong> CPU 内部用来加速工作性能的一个倍数,两者相乘才是 CPU 的主频。 </p>\n<p>除此之外,还有 <strong>前端总线</strong>、<strong>系统总线</strong></p>\n<p><strong>说明:</strong> 关于系统总线(Bus Speed)、前端总线(Front Side Bus,FSB)和外频,之前比较迷,去网上查,好嘛,更迷了。网上的内容,不是不能理解,而是太乱了,百度百科上说外频不能和前端总线的频率混淆,维基百科上说外频就是前端总线的频率,我表示呵呵。至于它们分别对此的解释,比如 CPU 架构的发展啊,单通道双通道啊等等,我就不再复制粘贴了,需要的可以自行搜索,只说一下我最后得出的结论。<strong>主频 = 系统总线 × 倍频</strong>,你没有看错,同时我们更多人知道的是后面这个公式 <em>主频 = 外频 × 倍频</em>,为了继续使用这个公式,现在你可以认为系统总线的频率就是外频。CPU-Z 是一款检测 CPU 的软件,通过它,你可能会更好的理解以上内容。下面是我的电脑实测图,红框内就是这一部分的数据。</p>\n<p><img src=\"/images/计算机硬件概述.jpg\" alt=\"\"></p>\n<p>Core Speed 是主频,Multiplier 是倍频系数,Bus Speed 是系统总线的频率,它是个定值,后两项的乘积就是主频。Rated FSB 是额定前端总线频率,我测的没有这一项,网上说是和新的 CPU 架构有关,具体的我也不清楚,谁知道的,望告知。</p>\n<h1 id=\"内存\"><a href=\"#内存\" class=\"headerlink\" title=\"内存\"></a>内存</h1><h2 id=\"DRAM\"><a href=\"#DRAM\" class=\"headerlink\" title=\"DRAM\"></a>DRAM</h2><p>个人计算机的内存主要组件为 <strong>动态随机访问内存(Dynamic Random Access Menmory,DRAM)</strong>,随机访问内存只有在通电时才能记录与使用,断电后数据就消失了。DRAM 根据技术的更新又分为好几代,使用比较广泛有 SDRAM 和 DDR SDRAM 两种。DDR SDRAM 是双倍数据传输速度(Double Data Rate),它可以在一次工作周期中进行两次数据的传递。现在使用的基本都是 DDR 了,而 DDR 也更新了好几代,现在最新的并可以买到的是 DDR4。</p>\n<h2 id=\"缓存\"><a href=\"#缓存\" class=\"headerlink\" title=\"缓存\"></a>缓存</h2><p>为了加快 CPU 的运行性能,都会 CPU 的内部集成缓存,现在的 CPU 一般会采用三级缓存。一级缓存都内置在 CPU 内部并与 CPU 同速运行,可以有效的提高 CPU 的运行效率。二级缓存,它是为了协调一级缓存和内存之间的速度。三级缓存是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的 CPU 中,只有约 5% 的数据需要从内存中调用,这进一步提高了 CPU 的效率。上图红框右面的 Cache 部分就是我的电脑的缓存。</p>\n<h1 id=\"显卡\"><a href=\"#显卡\" class=\"headerlink\" title=\"显卡\"></a>显卡</h1><p>显卡又称为 VGA(Video Graphics Array),它对于图形影像的显示扮演相当重要的角色。一般对于图形影像的显示重点在于分辨率和色彩深度,因为每个图像显示的颜色会占用内存,因此显卡上面会有一个内存的容量,称为显存。一些 3D 的运算早期是交给 CPU 去运行的,但是 CPU 并非完全针对这些 3D 来进行设计,而且 CPU 平时已经非常忙碌了。所以后来显卡厂商直接在显卡上面嵌入一个 3D 加速的芯片,称之为 GPU。</p>\n<p>除了 CPU、内存和显卡外,其他部分如硬盘等,不是核心部分,就不再啰嗦了。</p>\n<p><strong>说明:</strong> 该文章部分内容参考书籍《鸟哥的 Liunx 私房菜-基础学习篇》<br><br><br></p>\n","categories":["硬件"],"tags":["硬件"]},{"title":"Laravel 验证中的正则 regex","url":"http://mrzhouxiaofei.com/2017/12/09/Laravel 验证中的正则 regex/","content":"<p>Laravel 的验证功能非常强大,基本上常见的需求都有对应的验证规则,对于一些的特殊的验证需求,Laravel 也提供了正则验证。</p>\n<p>正则验证之前也用过一次,今天再次使用时,发现不行了,又看了一下官方文档,才知道问题出在哪,特此记录下来。</p>\n<p>官方文档:</p>\n<p><strong>regex:pattern</strong></p>\n<p>验证字段必须匹配给定正则表达式</p>\n<blockquote>\n<p>注:使用 regex 模式时,规则必须放在数组中,而不能使用管道分隔符,尤其是正则表达式中已经使用了管道符号时。</p>\n</blockquote>\n<p>之前使用正则验证,使用管道符 <strong>|</strong> 和其它规则分开,今天再次使用正则验证时,没有成功,使用时像下面这样:</p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">rules</span><span class=\"params\">()</span></span>{</div><div class=\"line\"> <span class=\"keyword\">return</span> [</div><div class=\"line\"> <span class=\"string\">'username'</span> => <span class=\"string\">'required|regex:/^[a-zA-Z0-9_-]{4,16}$/'</span>,</div><div class=\"line\"> <span class=\"string\">'month'</span> => <span class=\"string\">'required|regex:/^([1-9]|1[0-2])$/'</span>,</div><div class=\"line\"> ];</div><div class=\"line\">}</div></pre></td></tr></table></figure>\n<p>看了一下文档,使用正则验证时,规则必须放在数组中,改成下面这样就成功了:</p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">rules</span><span class=\"params\">()</span></span>{</div><div class=\"line\"> <span class=\"keyword\">return</span> [</div><div class=\"line\"> <span class=\"string\">'username'</span> => [</div><div class=\"line\"> <span class=\"string\">'required'</span>,</div><div class=\"line\"> <span class=\"string\">'regex:/^[a-zA-Z0-9_-]{4,16}$/'</span></div><div class=\"line\"> ],</div><div class=\"line\"> <span class=\"string\">'month'</span> => [</div><div class=\"line\"> <span class=\"string\">'required'</span>,</div><div class=\"line\"> <span class=\"string\">'regex:/^([1-9]|1[0-2])$/'</span></div><div class=\"line\"> ],</div><div class=\"line\"> ];</div><div class=\"line\">}</div></pre></td></tr></table></figure>\n<p>或者这样:</p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">rules</span><span class=\"params\">()</span></span>{</div><div class=\"line\"> <span class=\"keyword\">return</span> [</div><div class=\"line\"> <span class=\"string\">'username'</span> => <span class=\"keyword\">array</span>(</div><div class=\"line\"> <span class=\"string\">'required'</span>,</div><div class=\"line\"> <span class=\"string\">'regex:/^[a-zA-Z0-9_-]{4,16}$/'</span></div><div class=\"line\"> ),</div><div class=\"line\"> <span class=\"string\">'month'</span> => <span class=\"keyword\">array</span>(</div><div class=\"line\"> <span class=\"string\">'required'</span>,</div><div class=\"line\"> <span class=\"string\">'regex:/^([1-9]|1[0-2])$/'</span></div><div class=\"line\"> ),</div><div class=\"line\"> ];</div><div class=\"line\">}</div></pre></td></tr></table></figure>\n<p>之前能够成功,应该是正则中没有使用管道符 <strong>|</strong>,对于第一个 username 的验证,没有使用管道符,不放在在数组中,也是可以验证的,第二个 month 的验证就必须放在数组中了。不过为了规范起见,使用正则验证时,还是要把验证规则放到数组中。<br><br><br></p>\n","categories":["后端"],"tags":["PHP","Laravel"]},{"title":"PHP 中 this self static 的区别","url":"http://mrzhouxiaofei.com/2017/11/27/PHP 中 this self static 的区别/","content":"<h1 id=\"引入\"><a href=\"#引入\" class=\"headerlink\" title=\"引入\"></a>引入</h1><p>最近在做软件工程的课程设计,碰到一个问题,去扒 Laravel 源码,又搜索一番,发现是对 self static 的理解不深,才出现了问题,所以记录下来,避免再次犯同样的错误。</p>\n<h1 id=\"正文\"><a href=\"#正文\" class=\"headerlink\" title=\"正文\"></a>正文</h1><h2 id=\"this\"><a href=\"#this\" class=\"headerlink\" title=\"this\"></a>this</h2><p>this 比较好理解,就是指向当前对象,用于访问当前对象的非静态变量和非静态方法,它是和对象相关的;</p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><?php</span></div><div class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">Person</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">public</span> $name;</div><div class=\"line\"> </div><div class=\"line\"> <span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">getName</span><span class=\"params\">()</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"keyword\">$this</span>->name;</div><div class=\"line\"> }</div><div class=\"line\">}</div><div class=\"line\"> </div><div class=\"line\">$p = <span class=\"keyword\">new</span> Person();</div><div class=\"line\">$p2 = <span class=\"keyword\">new</span> Person();</div><div class=\"line\">$p->name = <span class=\"string\">\"小红\"</span>;</div><div class=\"line\">$p2->name = <span class=\"string\">\"小明\"</span>;</div><div class=\"line\">$p->getName(); <span class=\"comment\">// 小红</span></div><div class=\"line\">$p2->getName(); <span class=\"comment\">// 小明</span></div></pre></td></tr></table></figure>\n<p>上例中 new 了两个对象,并分别设置对象的 name 属性,getName() 中使用了 this 访问当前对象的 name 属性,所以分别输出了 name 的值。所以说,this 就是指向当前对象,不指向其他对象或类。</p>\n<h2 id=\"self\"><a href=\"#self\" class=\"headerlink\" title=\"self\"></a>self</h2><p>self 和 this 不同,它指向类本身,不指向任何实例化对象,一般用来访问类中的静态变量和静态方法;</p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><?php</span></div><div class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">Person</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">public</span> <span class=\"keyword\">static</span> $name = <span class=\"string\">\"小红\"</span>;</div><div class=\"line\"> </div><div class=\"line\"> <span class=\"keyword\">public</span> <span class=\"keyword\">static</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">getName</span><span class=\"params\">()</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"keyword\">self</span>::$name;</div><div class=\"line\"> }</div><div class=\"line\">}</div><div class=\"line\"> </div><div class=\"line\">$p = <span class=\"keyword\">new</span> Person();</div><div class=\"line\">$p2 = <span class=\"keyword\">new</span> Person();</div><div class=\"line\">$p::getName(); <span class=\"comment\">// 小红</span></div><div class=\"line\">$p2::getName(); <span class=\"comment\">// 小红</span></div><div class=\"line\">$p::$name = <span class=\"string\">\"小明\"</span>;</div><div class=\"line\">$p::getName(); <span class=\"comment\">// 小明</span></div><div class=\"line\">$p2::getName(); <span class=\"comment\">// 小明</span></div></pre></td></tr></table></figure>\n<p>上例中 new 了两个对象,并修改了其中一个对象的 name 属性,另一个对象的 name 属性值也改变了,所以说,self 是指向当前类的,和对象无关,所有的对象共用一个值。</p>\n<h2 id=\"static\"><a href=\"#static\" class=\"headerlink\" title=\"static\"></a>static</h2><p>static 和 self 一样,都是指向类,一般都用来访问类中的静态变量和静态方法,但是又有一些不一样,具体来讲:self 写在哪个类里,实际调用的就是这个类;static 则是写在父类里,然后通过子类用到了这个 static,这个 static 指向的是这个子类,官方称之为 <strong>后期静态绑定</strong> 。</p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div><div class=\"line\">17</div><div class=\"line\">18</div><div class=\"line\">19</div><div class=\"line\">20</div><div class=\"line\">21</div><div class=\"line\">22</div><div class=\"line\">23</div><div class=\"line\">24</div><div class=\"line\">25</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><?php</span></div><div class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">A</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">say</span><span class=\"params\">()</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"string\">\"Hello\"</span>;</div><div class=\"line\"> }</div><div class=\"line\"> </div><div class=\"line\"> <span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">saySelf</span><span class=\"params\">()</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">self</span>::say();</div><div class=\"line\"> }</div><div class=\"line\"> </div><div class=\"line\"> <span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">sayStatic</span><span class=\"params\">()</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">static</span>::say();</div><div class=\"line\"> }</div><div class=\"line\">}</div><div class=\"line\"> </div><div class=\"line\"><span class=\"class\"><span class=\"keyword\">class</span> <span class=\"title\">B</span> <span class=\"keyword\">extends</span> <span class=\"title\">A</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">public</span> <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">say</span><span class=\"params\">()</span> </span>{</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"string\">\"World\"</span>;</div><div class=\"line\"> }</div><div class=\"line\">}</div><div class=\"line\"> </div><div class=\"line\">$b = <span class=\"keyword\">new</span> B();</div><div class=\"line\">$b->say(); <span class=\"comment\">// World</span></div><div class=\"line\">$b->saySelf(); <span class=\"comment\">// Hello</span></div><div class=\"line\">$b->sayStatic(); <span class=\"comment\">// World</span></div></pre></td></tr></table></figure>\n<p>上例中可以看到,self 写在 A 类里,调用时就指向了 A 类,static 同样写在 A 类里,但是用 A 类的子类 B 类的对象去调用时,却指向了 B 类,在使用时,static 才确定指向哪个类,这就是 <strong>后期静态绑定</strong> 。</p>\n<p><a href=\"http://php.net/manual/zh/language.oop5.late-static-bindings.php\" target=\"_blank\" rel=\"external\">后期静态绑定</a></p>\n<h2 id=\"总结\"><a href=\"#总结\" class=\"headerlink\" title=\"总结\"></a>总结</h2><p>this 指向当前对象,用来访问当前对象的非静态变量和非静态方法;<br>self 指向类,一般用来访问当前类的静态变量和静态方法,运行之前已经确定指向哪个类;<br>static 指向类,一般用来访问当前类的静态变量和静态方法,但又 <strong>不限于</strong> 静态的调用,运行时才确定指向哪个类。<br><br><br></p>\n","categories":["后端"],"tags":["PHP"]},{"title":"Laravel5.5 + Vue2 + Element 环境搭建","url":"http://mrzhouxiaofei.com/2017/09/17/Laravel5.5 + Vue2 + Element 环境搭建/","content":"<h1 id=\"更新说明\"><a href=\"#更新说明\" class=\"headerlink\" title=\"更新说明\"></a>更新说明</h1><p><strong>2018 年 1 月 25 日更新</strong></p>\n<p>开始写这篇文章时,Element 的版本还是 1.4,现在已经来到 2.0 了,有些步骤需要修改,特此说明。</p>\n<h2 id=\"第-9-步,修改-Hello-vue-文件,使用-Element-组件-中\"><a href=\"#第-9-步,修改-Hello-vue-文件,使用-Element-组件-中\" class=\"headerlink\" title=\"第 9 步,修改 Hello.vue 文件,使用 Element 组件 中\"></a>第 9 步,<em>修改 Hello.vue 文件,使用 Element 组件</em> 中</h2><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\"><el-dialog v-model="visible"></div></pre></td></tr></table></figure>\n<p>修改为</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\"><el-dialog :visible.sync="visible"></div></pre></td></tr></table></figure>\n<h2 id=\"第-8-步,引入-Element-中,使用命令\"><a href=\"#第-8-步,引入-Element-中,使用命令\" class=\"headerlink\" title=\"第 8 步,引入 Element 中,使用命令\"></a>第 8 步,<em>引入 Element</em> 中,使用命令</h2><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm i element-ui -S</div></pre></td></tr></table></figure>\n<p>默认安装的 Element 是 2.0 版本,2.0 版本的主题文件夹,由 theme-default 改为了 theme-chalk,所以下面 <em>修改 resources/assets/js/app.js 文件</em> 中</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">import 'element-ui/lib/theme-default/index.css';</div></pre></td></tr></table></figure>\n<p>要改成</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">import 'element-ui/lib/theme-chalk/index.css';</div></pre></td></tr></table></figure>\n<p>当然,如果你想继续使用 1.4 版本的 Element 也是可以的,使用命令</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm i element-ui@legacy -S</div></pre></td></tr></table></figure>\n<p>安装的即是 1.4 版,自然的,主题文件夹也不需要修改了。</p>\n<h1 id=\"搭建说明\"><a href=\"#搭建说明\" class=\"headerlink\" title=\"搭建说明\"></a>搭建说明</h1><p>同类的教程网上也有不少,本文不是为了重复造轮子,只是在 Laravel5.5 LTS 推出之际,重新记录自己的搭建过程,避免以后再次踩坑。</p>\n<p>网上的许多教程都是基于 Laravel5 系列的不同版本,虽然大致过程都差不多,但是对于前端编译工具不甚了解的人来说,官方推荐的前端编译工具的改变也着实容易让人迷糊。</p>\n<p>为了便于理解,本文初次搭建时,尽量简单,能运行即可,关于前端编译工具,Vue 路由等等,后面再说。</p>\n<p>本文全部代码,可以到 github 上获取: </p>\n<p><a href=\"https://github.com/mrzhouxiaofei/Larvuent\" target=\"_blank\" rel=\"external\">https://github.com/mrzhouxiaofei/Larvuent</a></p>\n<h1 id=\"搭建过程\"><a href=\"#搭建过程\" class=\"headerlink\" title=\"搭建过程\"></a>搭建过程</h1><h2 id=\"1-新建-Laravel5-5-项目\"><a href=\"#1-新建-Laravel5-5-项目\" class=\"headerlink\" title=\"1.新建 Laravel5.5 项目\"></a>1.新建 Laravel5.5 项目</h2><p>在 Web 服务器目录下,使用 Composer 建立新项目<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">composer create-project --prefer-dist laravel/laravel Larvuent // 新项目名为 Larvuent</div></pre></td></tr></table></figure></p>\n<p>Larvuent 安装完成后,执行<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">cd Larvuent</div></pre></td></tr></table></figure></p>\n<p><strong>说明:建议配置虚拟主机</strong></p>\n<h2 id=\"2-安装前端依赖库\"><a href=\"#2-安装前端依赖库\" class=\"headerlink\" title=\"2.安装前端依赖库\"></a>2.安装前端依赖库</h2><p>进入 Larvuent 项目后,执行<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm install // 速度慢的请自行切换淘宝镜像 cnpm</div></pre></td></tr></table></figure></p>\n<h2 id=\"3-修改-Laravel-路由\"><a href=\"#3-修改-Laravel-路由\" class=\"headerlink\" title=\"3.修改 Laravel 路由\"></a>3.修改 Laravel 路由</h2><p>修改 <strong>routes/web.php</strong> 文件为<br><figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\">Route::get(<span class=\"string\">'/'</span>, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">()</span> </span>{</div><div class=\"line\">\t<span class=\"keyword\">return</span> view(<span class=\"string\">'index'</span>);</div><div class=\"line\">});</div></pre></td></tr></table></figure></p>\n<h2 id=\"4-新建-Hello-vue-文件\"><a href=\"#4-新建-Hello-vue-文件\" class=\"headerlink\" title=\"4.新建 Hello.vue 文件\"></a>4.新建 Hello.vue 文件</h2><p>在 <strong>resources/assets/js/components</strong> 目录下新建 Hello.vue 文件<br><figure class=\"highlight\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div><div class=\"line\">17</div><div class=\"line\">18</div><div class=\"line\">19</div><div class=\"line\">20</div><div class=\"line\">21</div><div class=\"line\">22</div><div class=\"line\">23</div></pre></td><td class=\"code\"><pre><div class=\"line\"><template></div><div class=\"line\"> <div></div><div class=\"line\"> <h1>Hello, Larvuent!</h1></div><div class=\"line\"> <p class=\"hello\">{{ msg }}</p></div><div class=\"line\"> </div></div><div class=\"line\"></template></div><div class=\"line\"> </div><div class=\"line\"><script></div><div class=\"line\">export default {</div><div class=\"line\"> data() {</div><div class=\"line\"> return {</div><div class=\"line\"> msg: 'This is a Laravel with Vue and Element Demo.'</div><div class=\"line\"> }</div><div class=\"line\"> }</div><div class=\"line\">}</div><div class=\"line\"></script></div><div class=\"line\"> </div><div class=\"line\"><style></div><div class=\"line\">.hello {</div><div class=\"line\"> font-size: 2em;</div><div class=\"line\"> color: green;</div><div class=\"line\">}</div><div class=\"line\"></style></div></pre></td></tr></table></figure></p>\n<h2 id=\"5-修改-app-js-文件,渲染组件\"><a href=\"#5-修改-app-js-文件,渲染组件\" class=\"headerlink\" title=\"5.修改 app.js 文件,渲染组件\"></a>5.修改 app.js 文件,渲染组件</h2><p>修改 <strong>resources/assets/js/app.js</strong> 文件<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"built_in\">require</span>(<span class=\"string\">'./bootstrap'</span>);</div><div class=\"line\"> </div><div class=\"line\"><span class=\"built_in\">window</span>.Vue = <span class=\"built_in\">require</span>(<span class=\"string\">'vue'</span>);</div><div class=\"line\"> </div><div class=\"line\"><span class=\"comment\">// Vue.component('example', require('./components/Example.vue')); // 注释掉</span></div><div class=\"line\"><span class=\"keyword\">import</span> Hello <span class=\"keyword\">from</span> <span class=\"string\">'./components/Hello.vue'</span>; <span class=\"comment\">// 引入Hello 组件</span></div><div class=\"line\"> </div><div class=\"line\"><span class=\"keyword\">const</span> app = <span class=\"keyword\">new</span> Vue({</div><div class=\"line\"> <span class=\"attr\">el</span>: <span class=\"string\">'#app'</span>,</div><div class=\"line\"> <span class=\"attr\">render</span>: <span class=\"function\"><span class=\"params\">h</span> =></span> h(Hello)</div><div class=\"line\">});</div></pre></td></tr></table></figure></p>\n<p><strong>说明:app.js 是构建 Vue 项目的主文件,最后所有的组件都会被引入到这个文件,在引入所有组件之前,bootstrap.js 文件做了一些初始化的操作。同时,因为有了 window.Vue = require(‘vue’) 这句话,就不再需要使用 import Vue from ‘vue’ 重复导入 Vue 了。</strong></p>\n<h2 id=\"6-新建-Laravel-视图文件,和-Vue-交互\"><a href=\"#6-新建-Laravel-视图文件,和-Vue-交互\" class=\"headerlink\" title=\"6.新建 Laravel 视图文件,和 Vue 交互\"></a>6.新建 Laravel 视图文件,和 Vue 交互</h2><p>在 <strong>resources/views</strong> 目录下新建 index.blade.php 文件<br><figure class=\"highlight html\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><!doctype html></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span> <span class=\"attr\">lang</span>=<span class=\"string\">\"en\"</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">head</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">meta</span> <span class=\"attr\">charset</span>=<span class=\"string\">\"UTF-8\"</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">title</span>></span>Larvuent<span class=\"tag\"></<span class=\"name\">title</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">head</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">body</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">id</span>=<span class=\"string\">\"app\"</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></div><div class=\"line\"> </div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span> <span class=\"attr\">src</span>=<span class=\"string\">\"{{ mix('js/app.js') }}\"</span>></span><span class=\"undefined\"></span><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">body</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></div></pre></td></tr></table></figure></p>\n<p><strong>说明:你可能在其他教程中看到有的在使用 assets 函数,这两个函数的主要区别就是 assets 函数会直接使用所填路径去 public 文件夹下找文件,而 mix 函数会自动加载带 hash 值的前端资源。这是和 Laravel 前端资源的缓存刷新相关的,如果现在还不明白,不要紧,你记得使用 mix 函数就好了,然后继续往后看。</strong></p>\n<h2 id=\"7-编译前端组件,运行\"><a href=\"#7-编译前端组件,运行\" class=\"headerlink\" title=\"7.编译前端组件,运行\"></a>7.编译前端组件,运行</h2><p>执行以下命令,编译前端资源<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm run dev</div></pre></td></tr></table></figure></p>\n<p>该命令默认会去执行根目录下的 webpack.mix.js 文件,使用 Laravel 提供的 Laravel Mix 编译资源,并将编译好的资源放在根目录 public 文件夹下。 </p>\n<p><strong>说明:前端编译工具有许多,比如 gulp、webpack 等等,Laravel 也为自己提供了开箱即用的编译工具,比如 Laravel5.3 及更早版本提供基于 gulp 的 Laravel Elixir 和从 Laravel5.4 开始提供基于 webpack 的 Laravel Mix,当然你也可以不使用官方提供的工具,自己去配置编译工具。这些编译工具的作用都是一样的,使用方法也大同小异。前面说过,本文第一次安装尽量简单,能运行即可,所以不再去配置前端编译工具,使用官方提供的即可。</strong></p>\n<p>访问项目 </p>\n<p><img src=\"/images/Larvuent_5.jpg\" alt=\"\"></p>\n<p>到目前为止,Laravel + Vue 已经完成了,下面开始引入 Element。</p>\n<h2 id=\"8-引入-Element\"><a href=\"#8-引入-Element\" class=\"headerlink\" title=\"8.引入 Element\"></a>8.引入 Element</h2><p>执行命令,安装 ElementUI<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm i element-ui -S</div></pre></td></tr></table></figure></p>\n<p>修改 <strong>resources/assets/js/app.js</strong> 文件<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">import</span> Hello <span class=\"keyword\">from</span> <span class=\"string\">'./components/Hello.vue'</span>; <span class=\"comment\">// 引入Hello 组件</span></div><div class=\"line\"><span class=\"keyword\">import</span> ElementUI <span class=\"keyword\">from</span> <span class=\"string\">'element-ui'</span>;</div><div class=\"line\"><span class=\"keyword\">import</span> <span class=\"string\">'element-ui/lib/theme-default/index.css'</span>;</div><div class=\"line\">Vue.use(ElementUI);</div></pre></td></tr></table></figure></p>\n<h2 id=\"9-修改-Hello-vue-文件,使用-Element-组件\"><a href=\"#9-修改-Hello-vue-文件,使用-Element-组件\" class=\"headerlink\" title=\"9.修改 Hello.vue 文件,使用 Element 组件\"></a>9.修改 Hello.vue 文件,使用 Element 组件</h2><p>修改 <strong>resources/assets/js/components/Hello.vue</strong> 文件为<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div><div class=\"line\">17</div><div class=\"line\">18</div><div class=\"line\">19</div><div class=\"line\">20</div><div class=\"line\">21</div><div class=\"line\">22</div><div class=\"line\">23</div><div class=\"line\">24</div><div class=\"line\">25</div><div class=\"line\">26</div></pre></td><td class=\"code\"><pre><div class=\"line\"><template></div><div class=\"line\"> <span class=\"xml\"><span class=\"tag\"><<span class=\"name\">div</span>></span></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">h1</span>></span>Hello, Larvuent!<span class=\"tag\"></<span class=\"name\">h1</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">el-button</span> @<span class=\"attr\">click</span>=<span class=\"string\">\"visible = true\"</span>></span>按钮<span class=\"tag\"></<span class=\"name\">el-button</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">el-dialog</span> <span class=\"attr\">v-model</span>=<span class=\"string\">\"visible\"</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">p</span>></span>欢迎使用 Element<span class=\"tag\"></<span class=\"name\">p</span>></span></div><div class=\"line\"> <span class=\"tag\"></<span class=\"name\">el-dialog</span>></span></div><div class=\"line\"> <span class=\"tag\"></<span class=\"name\">div</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">template</span>></span></div><div class=\"line\"> </div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">script</span>></span><span class=\"javascript\"></span></div><div class=\"line\"><span class=\"keyword\">export</span> <span class=\"keyword\">default</span> {</div><div class=\"line\"> data() {</div><div class=\"line\"> <span class=\"keyword\">return</span> {</div><div class=\"line\"> <span class=\"attr\">visible</span>: <span class=\"literal\">false</span></div><div class=\"line\"> }</div><div class=\"line\"> }</div><div class=\"line\">}</div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"> </div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">style</span>></span><span class=\"undefined\"></span></div><div class=\"line\">.hello {</div><div class=\"line\"> font-size: 2em;</div><div class=\"line\"> color: green;</div><div class=\"line\">}</div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">style</span>></span></div></pre></td></tr></table></figure></p>\n<h2 id=\"10-再次编译前端资源,运行\"><a href=\"#10-再次编译前端资源,运行\" class=\"headerlink\" title=\"10.再次编译前端资源,运行\"></a>10.再次编译前端资源,运行</h2><p>执行<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm run dev</div></pre></td></tr></table></figure></p>\n<p>访问项目,点击按钮 </p>\n<p><img src=\"/images/Larvuent_2.jpg\" alt=\"\"></p>\n<p>好了,到目前为止,Laravel5.5 + Vue2 + Element 的环境搭建已经完成了,为了方便理解,第一次的搭建过程尽量简洁。本文下面的部分将使用 Vue 路由等等,逐步完善,便于后期的开发。</p>\n<h1 id=\"完善\"><a href=\"#完善\" class=\"headerlink\" title=\"完善\"></a>完善</h1><h2 id=\"CSRF-防护\"><a href=\"#CSRF-防护\" class=\"headerlink\" title=\"CSRF 防护\"></a>CSRF 防护</h2><p>环境搭建完成后,访问项目,打开开发者模式,切换到 Console ,会看到以下报错</p>\n<p><img src=\"/images/Larvuent_3.jpg\" alt=\"\"></p>\n<p>Laravel 为了避免应用遭到跨站请求伪造攻击(CSRF),自动为每一个有效用户会话生成一个 CSRF 令牌,该令牌用于验证授权用户和发起请求者是否是同一个人。</p>\n<p>修改 <strong>resources/views/index.blade.php</strong> 文件为<br><figure class=\"highlight html\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><!doctype html></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span> <span class=\"attr\">lang</span>=<span class=\"string\">\"en\"</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">head</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">meta</span> <span class=\"attr\">charset</span>=<span class=\"string\">\"UTF-8\"</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">meta</span> <span class=\"attr\">name</span>=<span class=\"string\">\"csrf-token\"</span> <span class=\"attr\">content</span>=<span class=\"string\">\"{{ csrf_token() }}\"</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">title</span>></span>Larvuent<span class=\"tag\"></<span class=\"name\">title</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">head</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">body</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">id</span>=<span class=\"string\">\"app\"</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></div><div class=\"line\"> </div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span> <span class=\"attr\">src</span>=<span class=\"string\">\"{{ mix('js/app.js') }}\"</span>></span><span class=\"undefined\"></span><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">body</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></div></pre></td></tr></table></figure></p>\n<p>创建一个 meta 标签并将令牌保存到该 meta 标签中,问题可解决。</p>\n<h2 id=\"使用-Vue-Router\"><a href=\"#使用-Vue-Router\" class=\"headerlink\" title=\"使用 Vue Router\"></a>使用 Vue Router</h2><p>构建大型项目时,使用 Vue Router 将是一个好的方式,它可以帮助你更好的组织代码,优化路由。</p>\n<h3 id=\"1-安装-vue-router\"><a href=\"#1-安装-vue-router\" class=\"headerlink\" title=\"1.安装 vue-router\"></a>1.安装 vue-router</h3><p>执行命令,安装 vue-router<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm install vue-router --save-dev</div></pre></td></tr></table></figure></p>\n<h3 id=\"2-配置-vue-router\"><a href=\"#2-配置-vue-router\" class=\"headerlink\" title=\"2.配置 vue-router\"></a>2.配置 vue-router</h3><p>在 <strong>resources/assets/js</strong> 目录下新建目录 router ,同时在 router 目录下新建 index.js 文件<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">import</span> Vue <span class=\"keyword\">from</span> <span class=\"string\">'vue'</span>;</div><div class=\"line\"><span class=\"keyword\">import</span> VueRouter <span class=\"keyword\">from</span> <span class=\"string\">'vue-router'</span>;</div><div class=\"line\">Vue.use(VueRouter);</div><div class=\"line\"> </div><div class=\"line\"><span class=\"keyword\">export</span> <span class=\"keyword\">default</span> <span class=\"keyword\">new</span> VueRouter({</div><div class=\"line\"> <span class=\"attr\">saveScrollPosition</span>: <span class=\"literal\">true</span>,</div><div class=\"line\"> <span class=\"attr\">routes</span>: [</div><div class=\"line\"> {</div><div class=\"line\"> <span class=\"attr\">name</span>: <span class=\"string\">'hello'</span>,</div><div class=\"line\"> <span class=\"attr\">path</span>: <span class=\"string\">'/hello'</span>,</div><div class=\"line\"> <span class=\"attr\">component</span>: <span class=\"function\"><span class=\"params\">resolve</span> =></span> <span class=\"keyword\">void</span>(<span class=\"built_in\">require</span>([<span class=\"string\">'../components/Hello.vue'</span>], resolve))</div><div class=\"line\"> }</div><div class=\"line\"> ]</div><div class=\"line\">});</div></pre></td></tr></table></figure></p>\n<h3 id=\"3-引入-vue-router\"><a href=\"#3-引入-vue-router\" class=\"headerlink\" title=\"3.引入 vue-router\"></a>3.引入 vue-router</h3><p>在 <strong>resources/assets/js</strong> 目录下新建 App.vue 文件<br><figure class=\"highlight\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div><div class=\"line\">17</div><div class=\"line\">18</div><div class=\"line\">19</div></pre></td><td class=\"code\"><pre><div class=\"line\"><template></div><div class=\"line\"> <div></div><div class=\"line\"> <h1>Hello, {{ msg }}!</h1></div><div class=\"line\"> <router-view></router-view> <!-- 路由引入的组件将在这里被渲染 --></div><div class=\"line\"> </div></div><div class=\"line\"></template></div><div class=\"line\"> </div><div class=\"line\"><script></div><div class=\"line\">export default {</div><div class=\"line\"> data() {</div><div class=\"line\"> return {</div><div class=\"line\"> msg: 'Vue'</div><div class=\"line\"> }</div><div class=\"line\"> }</div><div class=\"line\">}</div><div class=\"line\"></script></div><div class=\"line\"> </div><div class=\"line\"><style></div><div class=\"line\"></style></div></pre></td></tr></table></figure></p>\n<p>修改 <strong>resources/assets/js/app.js</strong> 文件为<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"comment\">// import Hello from './components/Hello.vue';</span></div><div class=\"line\"><span class=\"keyword\">import</span> App <span class=\"keyword\">from</span> <span class=\"string\">'./App.vue'</span>;</div><div class=\"line\"><span class=\"keyword\">import</span> ElementUI <span class=\"keyword\">from</span> <span class=\"string\">'element-ui'</span>;</div><div class=\"line\"><span class=\"keyword\">import</span> <span class=\"string\">'element-ui/lib/theme-default/index.css'</span>;</div><div class=\"line\">Vue.use(ElementUI);</div><div class=\"line\"> </div><div class=\"line\"><span class=\"keyword\">import</span> router <span class=\"keyword\">from</span> <span class=\"string\">'./router/index.js'</span>; </div><div class=\"line\"> </div><div class=\"line\"><span class=\"keyword\">const</span> app = <span class=\"keyword\">new</span> Vue({</div><div class=\"line\"> <span class=\"attr\">el</span>: <span class=\"string\">'#app'</span>,</div><div class=\"line\"> router,</div><div class=\"line\"> <span class=\"attr\">render</span>: <span class=\"function\"><span class=\"params\">h</span> =></span> h(App)</div><div class=\"line\">});</div></pre></td></tr></table></figure></p>\n<h3 id=\"4-重新编译\"><a href=\"#4-重新编译\" class=\"headerlink\" title=\"4.重新编译\"></a>4.重新编译</h3><p>执行<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm run dev</div></pre></td></tr></table></figure></p>\n<p>通过路由访问 hello 组件 </p>\n<p><img src=\"/images/Larvuent_4.jpg\" alt=\"\"></p>\n<p>以后如果要添加组件,只需在 resources/assets/js/components 目录下新建 vue 文件,在 resources/assets/js/router/index.js 文件里引入,然后就可以通过路由访问了。</p>\n<h2 id=\"代码拆分\"><a href=\"#代码拆分\" class=\"headerlink\" title=\"代码拆分\"></a>代码拆分</h2><p>代码拆分是将一些不经常变动的代码提取出来,以避免每次都要重新编译,如果你频繁更新应用的 JavaScript,需要考虑对 vendor 库进行提取和拆分,这样的话,一次修改应用代码不会影响 vendor.js 文件的缓存。</p>\n<p>Laravel Mix 的 extract 方法可以实现这样的功能:</p>\n<p>修改项目根目录下的 webpack.mix.js 文件<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\">mix.js(<span class=\"string\">'resources/assets/js/app.js'</span>, <span class=\"string\">'public/js'</span>)</div><div class=\"line\"> .sass(<span class=\"string\">'resources/assets/sass/app.scss'</span>, <span class=\"string\">'public/css'</span>)</div><div class=\"line\"> .extract([<span class=\"string\">'vue'</span>,<span class=\"string\">'axios'</span>]);</div></pre></td></tr></table></figure></p>\n<p>extract 方法接收包含所有库的数组或你想要提取到 vendor.js 文件的模块,使用上述代码作为示例,Mix 将会生成如下文件:<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\">public/js/manifest.js // Webpack manifest runtime</div><div class=\"line\">public/js/vendor.js // vendor 库</div><div class=\"line\">public/js/app.js // 应用代码</div></pre></td></tr></table></figure></p>\n<p>同时修改 resources/views/index.blade.php 文件为<br><figure class=\"highlight html\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><!doctype html></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span> <span class=\"attr\">lang</span>=<span class=\"string\">\"en\"</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">head</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">meta</span> <span class=\"attr\">charset</span>=<span class=\"string\">\"UTF-8\"</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">meta</span> <span class=\"attr\">name</span>=<span class=\"string\">\"csrf-token\"</span> <span class=\"attr\">content</span>=<span class=\"string\">\"{{ csrf_token() }}\"</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">title</span>></span>Larvuent<span class=\"tag\"></<span class=\"name\">title</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">head</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">body</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">div</span> <span class=\"attr\">id</span>=<span class=\"string\">\"app\"</span>></span><span class=\"tag\"></<span class=\"name\">div</span>></span></div><div class=\"line\"> </div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span> <span class=\"attr\">src</span>=<span class=\"string\">\"{{ mix('js/manifest.js') }}\"</span>></span><span class=\"undefined\"></span><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span> <span class=\"attr\">src</span>=<span class=\"string\">\"{{ mix('js/vendor.js') }}\"</span>></span><span class=\"undefined\"></span><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span> <span class=\"attr\">src</span>=<span class=\"string\">\"{{ mix('js/app.js') }}\"</span>></span><span class=\"undefined\"></span><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">body</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></div></pre></td></tr></table></figure></p>\n<p>全局的 mix 函数会根据 public/mix-manifest.json 中的路径去加载对应的文件,同时也要注意引入三个 js 文件的顺序,以避免出错。</p>\n<p>重新执行命令,就可以了。<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm run dev</div></pre></td></tr></table></figure></p>\n<p>使用下面的命令,可以监视前端资源的改变,并自动编译。<br><figure class=\"highlight plain\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">npm run watch</div></pre></td></tr></table></figure></p>\n<h1 id=\"总结\"><a href=\"#总结\" class=\"headerlink\" title=\"总结\"></a>总结</h1><p>到目前为止,这篇文章也快写完了,为了便于理解,本文第一次搭建时,尽量简单,能运行即可,成功之后,再添加其它功能。前端编译工具使用基于 webpack 的 Laravel Mix,一般情况下,它可以满足大部分的需求,当然你也可以完全抛弃 Laravel Mix,配置自己的 webpack,后期如果有需求,可以再写一篇相关的文章。</p>\n<p>本文全部代码,可以到 github 上获取: </p>\n<p><a href=\"https://github.com/mrzhouxiaofei/Larvuent\" target=\"_blank\" rel=\"external\">https://github.com/mrzhouxiaofei/Larvuent</a></p>\n<p>如有疑问,欢迎回复交流。<br><br><br></p>\n","categories":["后端"],"tags":["PHP","环境搭建"]},{"title":"HTTP 协议详解","url":"http://mrzhouxiaofei.com/2017/09/17/HTTP 协议详解/","content":"<h1 id=\"HTTP-协议概述\"><a href=\"#HTTP-协议概述\" class=\"headerlink\" title=\"HTTP 协议概述\"></a>HTTP 协议概述</h1><p>HTTP 超文本传输协议,学过计算机网络的应该知道,所谓协议,就是指通信双方共同遵循的规范。HTTP 协议就是浏览器和服务器之间进行 “沟通” 的一种规范,它是互联网的基础协议,学习 Web 开发的都应当熟悉 HTTP 协议。</p>\n<h1 id=\"HTTP-协议特点\"><a href=\"#HTTP-协议特点\" class=\"headerlink\" title=\"HTTP 协议特点\"></a>HTTP 协议特点</h1><h2 id=\"无连接\"><a href=\"#无连接\" class=\"headerlink\" title=\"无连接\"></a>无连接</h2><h2 id=\"无状态\"><a href=\"#无状态\" class=\"headerlink\" title=\"无状态\"></a>无状态</h2><p><video style=\"width:760px;\" src=\"http://videos.mrzhouxiaofei.com/%E5%B1%B1%E4%B8%98.mp4\" controls=\"controls\"><br> your browser does not support the video tag<br></video><br><br><br></p>\n","categories":["后端"],"tags":["HTTP"]},{"title":"跨域问题解决方案之 JSONP","url":"http://mrzhouxiaofei.com/2017/08/09/跨域问题解决方案之 JSONP/","content":"<h2 id=\"什么是跨域\"><a href=\"#什么是跨域\" class=\"headerlink\" title=\"什么是跨域\"></a>什么是跨域</h2><p>由于浏览器同源策略的限制,为了保证安全,是不能执行其他网站的脚本的,通俗点来说,就是执行的 URL 不在你的网站下。跨域即绕过同源策略的限制,获取其他网站的数据。</p>\n<p>同源的定义:协议,域名,端口均相同。</p>\n<p>简单说明对 <a href=\"http://mrzhouxiaofei.com/test.js\">http://mrzhouxiaofei.com/test.js</a> 的同源检测情况:</p>\n<p><img src=\"/images/同源检测.jpg\" alt=\"\"></p>\n<h2 id=\"为什么跨域\"><a href=\"#为什么跨域\" class=\"headerlink\" title=\"为什么跨域\"></a>为什么跨域</h2><p>一般公司内部都会有许多不同的子域,举个例子,比如百度,假设 pan.baibu.com 需要获取用户的信息,就要去 user.baidu.com 下去获取,前者访问后者的数据就属于跨域,除此之外,引用其他网站的各种资源也属于跨域,总之,跨域的使用范围还是很广的。</p>\n<h2 id=\"怎么跨域\"><a href=\"#怎么跨域\" class=\"headerlink\" title=\"怎么跨域\"></a>怎么跨域</h2><p>跨域的方式有许多种,主要有 JSONP,CORS,以及通过 document.domain 来跨子域等等,感兴趣的可以了解一下其它几种跨域方式,本篇文章将主要介绍目前使用较多的 JSONP 方式。</p>\n<h2 id=\"JSON-和-JSONP\"><a href=\"#JSON-和-JSONP\" class=\"headerlink\" title=\"JSON 和 JSONP\"></a>JSON 和 JSONP</h2><p>介绍通过 JSONP 跨域之前,先理解 JSON 和 JSONP 这两个概念。</p>\n<p><strong>JSON</strong> 不用多解释,之前接触的也比较多,它是一种数据交换格式,在它出现之前,XML 曾一统天下,它出现之后,抢夺了 XML 的半壁江山,并且越来越流行。</p>\n<p>JSON 的优点:</p>\n<ol>\n<li>基于纯文本,跨平台传递极其简单;</li>\n<li>JavaScript 原生支持,后台语言几乎全部支持;</li>\n<li>轻量级数据格式,占用字符数量极少,特别适合互联网传递;</li>\n<li>可读性较强</li>\n</ol>\n<p><strong>JSONP</strong> (JSON with Padding)是数据格式 JSON 的一种“使用模式”,可以让网页从别的网域要数据,也即跨域获取数据。简单来说,JSONP 就是一种开发人员创造出的非官方跨域数据交互协议。学过计算机网络的同学,应该比较容易理解什么是协议。</p>\n<h2 id=\"通过-JSONP-跨域\"><a href=\"#通过-JSONP-跨域\" class=\"headerlink\" title=\"通过 JSONP 跨域\"></a>通过 JSONP 跨域</h2><h3 id=\"JSONP-的产生\"><a href=\"#JSONP-的产生\" class=\"headerlink\" title=\"JSONP 的产生\"></a>JSONP 的产生</h3><p>我们知道,通过 ajax 请求文件存在跨域无权访问时,无论你是什么网页,一律不被允许,不过我们一定有过这种情况:</p>\n<ol>\n<li>通过 script 标签引入过域外文件,比如引入百度的 JQuery;</li>\n<li>通过 img 标签引入过于在线的图片;</li>\n</ol>\n<p>通过以上两种情况,我们发现 Web 页面上调用 Js 文件或引用图片是不受跨域影响的,进一步发现,凡是拥有 src 这个属性的标签,都拥有跨域的能力。</p>\n<p>这样以来服务器把客户端需要的数据封装成包含 JSON 的 Js 文件 ,客户端就可以通过 script 标签,调用服务器动态生成的 Js 文件,来实现跨域获取数据了。</p>\n<p>客服端获取数据后,就可以对数据经行处理了,这看起来非常 ajax,但其实并不一样。</p>\n<p>为了便于客户端使用数据,逐渐形成了一种非正式的传输协议,这种协议就是 JSONP,该协议的一个特点就是允许用户传递一个 callback 参数给服务器,然后服务器返回数据时会将这个 callback 参数作为函数名来包裹住 JSON 数据,这样客户端就可以随意定制自己的函数来自动处理返回的数据了。</p>\n<h3 id=\"JSONP-的实现\"><a href=\"#JSONP-的实现\" class=\"headerlink\" title=\"JSONP 的实现\"></a>JSONP 的实现</h3><p>1.假设远程服务器 mrzhouxiaofei.com 根目录下有这样一个文件 test.js</p>\n<figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">alert(<span class=\"string\">\"我是远程数据\"</span>)</div></pre></td></tr></table></figure>\n<p>本地服务器 localhost 下有个 index.html</p>\n<figure class=\"highlight html\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><!DOCTYPE html></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span> <span class=\"attr\">lang</span>=<span class=\"string\">\"en\"</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">head</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">title</span>></span><span class=\"tag\"></<span class=\"name\">title</span>></span> </div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">head</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">body</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span> <span class=\"attr\">src</span>=<span class=\"string\">\"http://mrzhouxiaofei.com/test.js\"</span>></span><span class=\"undefined\"></span><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">body</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></div></pre></td></tr></table></figure>\n<p>毫无疑问,页面弹出一个提示框,显示跨域调用成功。</p>\n<p>2.假设远程服务器 mrzhouxiaofei.com 根目录下有这样一个文件 test.js</p>\n<figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div></pre></td><td class=\"code\"><pre><div class=\"line\">doSomething({<span class=\"string\">\"info\"</span>: <span class=\"string\">\"我是远程数据\"</span>})</div></pre></td></tr></table></figure>\n<p>本地服务器 localhost 下有个 jsonp.html 页面,其中定义了一个函数,然后在远程 test.js 中传入数据进行调用</p>\n<figure class=\"highlight html\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><!DOCTYPE html></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span> <span class=\"attr\">lang</span>=<span class=\"string\">\"en\"</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">head</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">title</span>></span><span class=\"tag\"></<span class=\"name\">title</span>></span> </div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">head</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">body</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span>></span><span class=\"javascript\"></span></div><div class=\"line\"> <span class=\"keyword\">var</span> doSomething = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">data</span>) </span>{</div><div class=\"line\"> alert(<span class=\"string\">\"远程数据:\"</span> + data.info)</div><div class=\"line\"> }</div><div class=\"line\"> <span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span> <span class=\"attr\">src</span>=<span class=\"string\">\"http://mrzhouxiaofei.com/test.js\"</span>></span><span class=\"undefined\"></span><span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">body</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></div></pre></td></tr></table></figure>\n<p>运行之后,页面弹出提示窗口,并且跨域获取了远程的数据,但是怎么让服务器知道它应该调用哪个客户端的函数呢?</p>\n<p>3.这次先写本地服务器 localhost 下的 jsonp.html 的代码,代码如下:</p>\n<figure class=\"highlight html\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div><div class=\"line\">17</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><!DOCTYPE html></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span> <span class=\"attr\">lang</span>=<span class=\"string\">\"en\"</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">head</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">title</span>></span><span class=\"tag\"></<span class=\"name\">title</span>></span> </div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">head</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">body</span>></span></div><div class=\"line\"> <span class=\"tag\"><<span class=\"name\">script</span>></span><span class=\"javascript\"></span></div><div class=\"line\"> <span class=\"keyword\">var</span> doSomething = <span class=\"function\"><span class=\"keyword\">function</span>(<span class=\"params\">data</span>) </span>{</div><div class=\"line\"> alert(<span class=\"string\">\"远程数据:\"</span> + data.info)</div><div class=\"line\"> }</div><div class=\"line\"> </div><div class=\"line\"> <span class=\"keyword\">var</span> script = <span class=\"built_in\">document</span>.createElement(<span class=\"string\">'script'</span>)</div><div class=\"line\"> script.src = <span class=\"string\">\"http://mrzhouxiaofei.com/test.js?callback=doSomething\"</span></div><div class=\"line\"> <span class=\"built_in\">document</span>.getElementsByTagName(<span class=\"string\">'body'</span>)[<span class=\"number\">0</span>].appendChild(script)</div><div class=\"line\"> <span class=\"tag\"></<span class=\"name\">script</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">body</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></div></pre></td></tr></table></figure>\n<p>这次的代码不再写死,而是实现了动态查询,而这正是 JSONP 实现的核心部分,通过代码,可以看到,客户端调用的 URL,传入了一个 callback 参数,告诉服务器我的本地函数为 doSomething,这时服务器就会把客户端需要的数据传入到这个函数内,供客户端的调用,这样就完成了一次请求过程。</p>\n<p>远程服务器将要返回的数据如下:</p>\n<figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div></pre></td><td class=\"code\"><pre><div class=\"line\">doSomething({</div><div class=\"line\"> <span class=\"string\">\"id\"</span>: <span class=\"number\">1001</span>,</div><div class=\"line\"> <span class=\"string\">\"info\"</span>: <span class=\"string\">\"我是远程数据\"</span></div><div class=\"line\">})</div></pre></td></tr></table></figure>\n<p>到此为止,客户端就能跨域获取数据了,另外一点,<strong>JSONP 只能发送 GET 请求,不能发送 POST 请求</strong>。</p>\n<p><strong>说明:</strong>该文章部分内容参考 <a href=\"http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html\" target=\"_blank\" rel=\"external\">【原创】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例</a> ,看不懂的,可以看看这篇文章。<br><br><br></p>\n","categories":["前端"],"tags":["JavaScript","跨域","JSONP"]},{"title":"摔跤吧 爸爸","url":"http://mrzhouxiaofei.com/2017/07/17/摔跤吧 爸爸/","content":"<p><img src=\"/images/摔跤吧爸爸.jpg\" alt=\"\"></p>\n<p>今天下午,小组组织观看了印度电影《摔跤吧 爸爸》,之后进行了亲切而友好的讨论,花了一整个下午的时间,收获颇丰。</p>\n<p>电影讲述了一个全国摔跤冠军,为生活所迫,放弃运动生涯,转而希望培养自己的儿子,无奈生了四个女儿,偶然间发现两个女儿拥有摔跤天赋,继而培养自己的两个女儿成为女子摔跤冠军,打破印度传统的励志故事。这个电影属于那种你看了开头就基本能猜到结局的电影,然而却能做到全程无尿点,让你痴迷于演员的演技,实属不易。</p>\n<p>看完整部电影,给我留下深刻印象的莫过于电影中的音乐了,尽管语言不通,但是适时响起的音乐,还是让我产生了共鸣。在我的印象中,经典的电影不仅仅是故事好,演员演技棒,而且音乐也一定很不错,这部电影满足了我对经典的要求。</p>\n<p>电影中的父亲,梦想着有一天能获得世界摔跤冠军,为印度赢得一块金牌,后来经历一系列的事,转而开始培养自己的两个女儿。在印度那样一个女人露腿都会被人议论纷纷的社会中,可想而知,父亲和两个女儿受到的阻力是巨大的。然而父亲坚定的信念,对金牌的执著,以及两个女儿在听到女伴结婚时说的话之后的顿悟,都是对冲破阻力最大的帮助。在经历一番之后,最终,两个女儿都获得了世界摔跤冠军。</p>\n<p>电影中的父亲为什么对金牌有那么深的执念?其实了解一下印度就知道了,印度一直要成为一个大国,而且随着近年来的高速发展,确实也取得了重大的成就,在一些重要的场合也有了一定的话语权。可是,一到大型的国际运动赛事,印度人就集体消失了,这对于一个大国来说,恐怕是不合适的。曾经我们也是这样,还记得李宁“兵败汉城”之后,甚至有人直接给他寄刀子。我们经过数十年的发展,甚至直到 2008 年奥运会之后,才不再唯金牌论,而是开始关注运动员本身。这样才会有傅园慧,宁泽涛,尽管没有在奥运会上获得金牌,却依然受到大家的喜爱的运动员。对于印度来说,想要度过这样一个阶段,恐怕还需要一些时间。</p>\n<p>电影上映之后,票房尚好,口碑也很不错,然而却有一些不同的声音。比如批评父亲的专权,批评父亲为了让女儿实现自己的梦想,强迫她们做自己不喜欢的事,没有让她们选择自己的未来。其实我们这样说是不合适的,你没有站在那样一个社会中,只是靠了解和倾听,是永远也感受不到的。讲个真事,有一个人早年间逃荒到了黑龙江一个偏远的山村,后来生了七个女儿一个儿子,这个人懂得一点文化,知道知识的重要。于是逼迫孩子们读书,孩子们不听话时,甚至不惜体罚,后来孩子们都考上了大学,离开了山村。女儿们后来谈起父亲,依然会说父亲残忍,专权,不给她们自由,可是却没有一个人埋怨父亲。讲这个例子,可能不太合适,毕竟逼迫孩子们读书和逼迫女儿去练摔跤是不能相提并论的。但是在电影中却是最合适的,首先两个女儿并没有一个明确的目标,如果不是父亲的干预,可能上几年学,然后在十四岁的时候嫁给一个素未谋面的男人;其次他们的父亲曾经是全国摔跤冠军,这是一个极大的资源,父亲有着丰富的经验,能给她们最合适的指导。如果说父亲只是为实现自己的梦想,把女儿当作实现梦想的工具,那么在女儿不听话时,就应该会有体罚的桥段。在电影中,完全没有这样的情节,甚至最生气的一次,女儿去参加别人的婚礼,也只是打了大侄子一巴掌。最重要的是,父亲也定了一年之约,如果一年后,女儿们还没爱上摔跤,就永远放弃。由此可见,父亲是深深的爱着女儿,并尊重她们的选择,所谓专权,是不成立的。</p>\n<p>电影之外:饰演父亲的阿米尔 汗,是印度国宝级演员,不仅主演了多部经典的电影,而且一直致力于公益等社会事业,印度有他,国之甚兴。<br><br><br> </p>\n","categories":["随笔"],"tags":["影评"]},{"title":"JavaScript 中的数组函数","url":"http://mrzhouxiaofei.com/2017/06/10/JavaScript 中的数组函数/","content":"<p><em>JavaScript 中也有很多数组函数:</em></p>\n<p>indexOf()<br>搜索一个指定的元素的位置<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'java'</span>,<span class=\"string\">'php'</span>,<span class=\"string\">'js'</span>];</div><div class=\"line\">alert(a.indexOf(<span class=\"string\">'php'</span>)); <span class=\"comment\">// 返回 1</span></div></pre></td></tr></table></figure></p>\n<p>slice()<br>截取数组的部分元素,返回一个新数组<br>该函数类似字符串函数中的 slice()<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'java'</span>,<span class=\"string\">'php'</span>,<span class=\"string\">'js'</span>];</div><div class=\"line\">alert(a.slice(<span class=\"number\">1</span>,<span class=\"number\">2</span>)); <span class=\"comment\">// 返回 php</span></div></pre></td></tr></table></figure></p>\n<p>push() pop()<br>向数组末尾添加一个或多个元素,删除数组最后一个元素<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'java'</span>,<span class=\"string\">'php'</span>];</div><div class=\"line\">alert(a.push(<span class=\"string\">'js'</span>)); <span class=\"comment\">// 返回 3</span></div><div class=\"line\">alert(a.pop()); <span class=\"comment\">//返回 js</span></div></pre></td></tr></table></figure></p>\n<p>unshift() shift()<br>向数组头部添加一个或多个元素,删除并返回第一个元素<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'java'</span>,<span class=\"string\">'php'</span>];</div><div class=\"line\">alert(a.unshift(<span class=\"string\">'js'</span>)); <span class=\"comment\">// 返回 3</span></div><div class=\"line\">alert(a.shift()); <span class=\"comment\">//返回 js</span></div></pre></td></tr></table></figure></p>\n<p>sort()<br>对数组的元素进行排序<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'mysql'</span>,<span class=\"string\">'php'</span>,<span class=\"string\">'js'</span>];</div><div class=\"line\">alert(a.sort()); <span class=\"comment\">// 返回 js,mysql,php</span></div></pre></td></tr></table></figure></p>\n<p>reverse()<br>颠倒数组中的元素<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'java'</span>,<span class=\"string\">'php'</span>,<span class=\"string\">'js'</span>];</div><div class=\"line\">alert(a.reverse()); <span class=\"comment\">// 返回 js,php,java</span></div></pre></td></tr></table></figure></p>\n<p>splice()<br>从指定的索引开始删除若干元素,然后再从该位置添加若干元素<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'java'</span>,<span class=\"string\">'php'</span>,<span class=\"string\">'js'</span>];</div><div class=\"line\">a.splice(<span class=\"number\">1</span>,<span class=\"number\">0</span>,<span class=\"string\">'mysql'</span>); </div><div class=\"line\">alert(a); <span class=\"comment\">// 返回 java,mysql,php,js</span></div></pre></td></tr></table></figure></p>\n<p>concat()<br>连接两个或多个数组,返回新数组<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"number\">1</span>,<span class=\"number\">2</span>,<span class=\"number\">3</span>];</div><div class=\"line\"><span class=\"keyword\">var</span> b = [<span class=\"number\">4</span>,<span class=\"number\">5</span>];</div><div class=\"line\">alert(a.concat(b)); <span class=\"comment\">//返回 1,2,3,4,5</span></div></pre></td></tr></table></figure></p>\n<p>join()<br>将数组中每个元素都用指定的字符串连接起来,返回新字符串<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = [<span class=\"string\">'java'</span>,<span class=\"string\">'php'</span>,<span class=\"string\">'js'</span>];</div><div class=\"line\">alert(a.join(<span class=\"string\">\"-\"</span>)); <span class=\"comment\">//返回 java-php-js</span></div></pre></td></tr></table></figure></p>\n<p><br><br></p>\n","categories":["前端"],"tags":["JavaScript"]},{"title":"JavaScript 中常用的字符串函数","url":"http://mrzhouxiaofei.com/2017/06/03/JavaScript 中常用的字符串函数/","content":"<p><em>JavaScript 中有很多字符串函数,其中一些较常用的总结如下:</em></p>\n<p>toUpperCase()<br>把一个字符串全部转换为大写</p>\n<p>toLowerCase()<br>把一个字符串全部转换为小写</p>\n<p>charAt(index)<br>返回指定位置的字符<br>Js 没有字符数据类型,即 char 类型,所以返回的字符是长度为 1 的字符串<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.charAt(<span class=\"number\">0</span>)); <span class=\"comment\">//返回 H</span></div></pre></td></tr></table></figure></p>\n<p>concat()<br>用于连接两个或多个字符串<br>通常使用 “+” 运算符会更简便一些<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello'</span>;</div><div class=\"line\"><span class=\"keyword\">var</span> b = <span class=\"string\">','</span>;</div><div class=\"line\"><span class=\"keyword\">var</span> c = <span class=\"string\">'world'</span></div><div class=\"line\">alert(a.concat(b,c)); <span class=\"comment\">//返回 Hello,world</span></div></pre></td></tr></table></figure></p>\n<p>indexOf()<br>返回某个指定的字符串值在字符串中首次出现的位置<br>若未找到,返回 -1<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.indexOf(<span class=\"string\">'l'</span>)); <span class=\"comment\">//返回 2</span></div></pre></td></tr></table></figure></p>\n<p>match()<br>可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.match(<span class=\"string\">'world'</span>)); <span class=\"comment\">//返回 world</span></div><div class=\"line\">alert(a.match(<span class=\"string\">'WORLD'</span>)); <span class=\"comment\">//返回 null</span></div></pre></td></tr></table></figure></p>\n<p>replace()<br>用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串<br>该函数功能强大<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.replace(<span class=\"regexp\">/world/</span>,<span class=\"string\">'JavaScript'</span>)); <span class=\"comment\">//返回 Hello,JavaScript</span></div></pre></td></tr></table></figure></p>\n<p>search()<br>用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.search(<span class=\"regexp\">/world/</span>)); <span class=\"comment\">//返回 6</span></div><div class=\"line\">alert(a.search(<span class=\"regexp\">/WORLD/</span>)); <span class=\"comment\">//返回 -1</span></div><div class=\"line\">alert(a.search(<span class=\"regexp\">/WORLD/i</span>)); <span class=\"comment\">//返回 6</span></div></pre></td></tr></table></figure></p>\n<p>split()<br>用于把一个字符串分割成字符串数组<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello'</span>;</div><div class=\"line\">alert(a.split(<span class=\"string\">\"\"</span>)); <span class=\"comment\">//返回 H,e,l,l,o</span></div></pre></td></tr></table></figure></p>\n<h3 id=\"三个分割字符串函数\"><a href=\"#三个分割字符串函数\" class=\"headerlink\" title=\"三个分割字符串函数\"></a>三个分割字符串函数</h3><p>slice()<br>提取字符串的某个部分,并以新的字符串返回被提取的部分<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.slice(<span class=\"number\">6</span>)); <span class=\"comment\">//返回 world</span></div><div class=\"line\">alert(a.slice(<span class=\"number\">6</span>,<span class=\"number\">10</span>)); <span class=\"comment\">//返回 worl</span></div></pre></td></tr></table></figure></p>\n<p>substring()<br>用于提取字符串中介于两个指定下标之间的字符<br>该函数不接受负的参数<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.substring(<span class=\"number\">6</span>)); <span class=\"comment\">//返回 world</span></div><div class=\"line\">alert(a.substring(<span class=\"number\">6</span>,<span class=\"number\">10</span>)); <span class=\"comment\">//返回 worl</span></div></pre></td></tr></table></figure></p>\n<p>substr()<br>可在字符串中抽取从 start 下标开始的指定数目的字符<br>ECMAscript 没有对该方法进行标准化,因此反对使用它<br><figure class=\"highlight js\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"keyword\">var</span> a = <span class=\"string\">'Hello,world'</span>;</div><div class=\"line\">alert(a.substr(<span class=\"number\">6</span>,<span class=\"number\">5</span>)); <span class=\"comment\">//返回 world</span></div></pre></td></tr></table></figure></p>\n<p>slice()、substring() 和 substr() (不建议使用)都可返回字符串的指定部分。slice() 比 substring() 要灵活一些,因为它允许使用负数作为参数。slice() 与 substr() 有所不同,因为它用两个字符的位置来指定子串,而 substr() 则用字符位置和长度来指定子串。<br><br><br></p>\n","categories":["前端"],"tags":["JavaScript"]},{"title":"PHP 实现邮件发送(PHPMailer+QQ邮箱)","url":"http://mrzhouxiaofei.com/2017/03/13/PHP 实现邮件发送(PHPMailer+QQ邮箱)/","content":"<p>最近复习原生 PHP,看到邮件函数这一部分,就试着写一下邮件功能,在网上搜了一下,主要有两种实现方式:<br> <strong>1.PHP 自带的 mail() 函数</strong><br> <strong>2.封装的 smtp 邮件发送类</strong></p>\n<p>下面来一一介绍</p>\n<h2 id=\"PHP-自带的-mail-函数\"><a href=\"#PHP-自带的-mail-函数\" class=\"headerlink\" title=\"PHP 自带的 mail() 函数\"></a>PHP 自带的 mail() 函数</h2><p>浏览一下 PHP 文档,mail() 函数的注释如下:</p>\n<p><img src=\"http://img.blog.csdn.net/20170311144907107?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"\"><br>即若要使用 mail() 函数,需要本地安装一个邮件系统或者必须设置一台不需要中继的邮件发送服务器,但现在要找到一台不需要身份验证的邮件发送中继几乎不可能,所以使用 mail() 函数往往无法成功发送电子邮件,对使用邮件系统感兴趣的,可以自己研究。而使用封装的smtp邮件发送类来实现,则要方便的多。</p>\n<h2 id=\"封装的-smtp-邮件发送类\"><a href=\"#封装的-smtp-邮件发送类\" class=\"headerlink\" title=\"封装的 smtp 邮件发送类\"></a>封装的 smtp 邮件发送类</h2><p>封装的smtp邮件发送类,网上可以找到很多,其中开源的 PHPMailer 是其中比较流行的一个,只需简单配置,即可使用,想了解更多,请移步 <a href=\"http://baike.baidu.com/link?url=gK7jI0Z90YK7TgX-dbAtjva9_5K3J119D2Q2T8zfZY24AC1Q5oWduRHzTPwJiPV7SEQ3MCFtURg4GXb-Dzh8rdit8iiawGyIR9fK8tNCxZ_\" target=\"_blank\" rel=\"external\">PHPMailer</a> PHPMailer开源地址:<a href=\"https://github.com/PHPMailer/PHPMailer\" target=\"_blank\" rel=\"external\">https://github.com/PHPMailer/PHPMailer</a></p>\n<p>可以直接把项目 clone 下来,或者下载 zip 压缩文件,在配置之前,需要开启邮箱的 smtp 功能,这里以 QQ 邮箱为例:</p>\n<p>登录 QQ 邮箱,点击<strong>设置</strong><br><img src=\"http://img.blog.csdn.net/20170311155901248?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"></p>\n<p><strong>账户</strong><br><img src=\"http://img.blog.csdn.net/20170311155920354?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"></p>\n<p>拉到最后,找到<br><img src=\"http://img.blog.csdn.net/20170311160214608?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"></p>\n<p>根据提示,开启前两项服务,然后生成授权码,记下来,之后配置会用<br><img src=\"http://img.blog.csdn.net/20170311160448283?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"></p>\n<p>clone 下来的 PHPMailer 项目的 README 文件提供了一个简单的引入例子<br><strong>A Simple Example</strong></p>\n<figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div><div class=\"line\">17</div><div class=\"line\">18</div><div class=\"line\">19</div><div class=\"line\">20</div><div class=\"line\">21</div><div class=\"line\">22</div><div class=\"line\">23</div><div class=\"line\">24</div><div class=\"line\">25</div><div class=\"line\">26</div><div class=\"line\">27</div><div class=\"line\">28</div><div class=\"line\">29</div><div class=\"line\">30</div><div class=\"line\">31</div><div class=\"line\">32</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><?php</span></div><div class=\"line\"><span class=\"keyword\">require</span> <span class=\"string\">'PHPMailerAutoload.php'</span>;</div><div class=\"line\">$mail = <span class=\"keyword\">new</span> PHPMailer;</div><div class=\"line\"><span class=\"comment\">//$mail->SMTPDebug = 3; // Enable verbose debug output</span></div><div class=\"line\"> </div><div class=\"line\">$mail->isSMTP(); <span class=\"comment\">// Set mailer to use SMTP</span></div><div class=\"line\">$mail->Host = <span class=\"string\">'smtp1.example.com;smtp2.example.com'</span>; <span class=\"comment\">// Specify main and backup SMTP servers</span></div><div class=\"line\">$mail->SMTPAuth = <span class=\"keyword\">true</span>; <span class=\"comment\">// Enable SMTP authentication</span></div><div class=\"line\">$mail->Username = <span class=\"string\">'[email protected]'</span>; <span class=\"comment\">// SMTP username</span></div><div class=\"line\">$mail->Password = <span class=\"string\">'secret'</span>; <span class=\"comment\">// SMTP password</span></div><div class=\"line\">$mail->SMTPSecure = <span class=\"string\">'tls'</span>; <span class=\"comment\">// Enable TLS encryption, `ssl` also accepted</span></div><div class=\"line\">$mail->Port = <span class=\"number\">587</span>; <span class=\"comment\">// TCP port to connect to</span></div><div class=\"line\"> </div><div class=\"line\">$mail->setFrom(<span class=\"string\">'[email protected]'</span>, <span class=\"string\">'Mailer'</span>);</div><div class=\"line\">$mail->addAddress(<span class=\"string\">'[email protected]'</span>, <span class=\"string\">'Joe User'</span>); <span class=\"comment\">// Add a recipient</span></div><div class=\"line\">$mail->addAddress(<span class=\"string\">'[email protected]'</span>); <span class=\"comment\">// Name is optional</span></div><div class=\"line\">$mail->addReplyTo(<span class=\"string\">'[email protected]'</span>, <span class=\"string\">'Information'</span>);</div><div class=\"line\">$mail->addCC(<span class=\"string\">'[email protected]'</span>);</div><div class=\"line\">$mail->addBCC(<span class=\"string\">'[email protected]'</span>);</div><div class=\"line\"> </div><div class=\"line\">$mail->addAttachment(<span class=\"string\">'/var/tmp/file.tar.gz'</span>); <span class=\"comment\">// Add attachments</span></div><div class=\"line\">$mail->addAttachment(<span class=\"string\">'/tmp/image.jpg'</span>, <span class=\"string\">'new.jpg'</span>); <span class=\"comment\">// Optional name</span></div><div class=\"line\">$mail->isHTML(<span class=\"keyword\">true</span>); <span class=\"comment\">// Set email format to HTML</span></div><div class=\"line\">$mail->Subject = <span class=\"string\">'Here is the subject'</span>;</div><div class=\"line\">$mail->Body = <span class=\"string\">'This is the HTML message body <b>in bold!</b>'</span>;</div><div class=\"line\">$mail->AltBody = <span class=\"string\">'This is the body in plain text for non-HTML mail clients'</span>;</div><div class=\"line\"><span class=\"keyword\">if</span>(!$mail->send()) {</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"string\">'Message could not be sent.'</span>;</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"string\">'Mailer Error: '</span> . $mail->ErrorInfo;</div><div class=\"line\">} <span class=\"keyword\">else</span> {</div><div class=\"line\"> <span class=\"keyword\">echo</span> <span class=\"string\">'Message has been sent'</span>;</div><div class=\"line\">}</div></pre></td></tr></table></figure>\n<p>在 PHPMailer 文件夹下,新建一个 index.php 文件,复制粘贴以上代码,修改各项配置</p>\n<p><img src=\"http://img.blog.csdn.net/20170311162934199?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"></p>\n<p>由于使用了 SSL 连接,所以需要开启PHP的 openssl 扩展,这里不再赘述,配置完之后,放在 Web 服务器下,访问 index.php,正常的话,就能收到一封测试邮件了,如果失败,可以根据报错信息进行排查。</p>\n<h2 id=\"最小化安装-推荐\"><a href=\"#最小化安装-推荐\" class=\"headerlink\" title=\"最小化安装(推荐)\"></a>最小化安装(推荐)</h2><p>直接把整个 PHPMailer 项目放到服务器上,未免太浪费空间,而且项目中的许多文件都是没用的,所以 README 文件中也提到了最小化安装<br><img src=\"http://img.blog.csdn.net/20170311164154835?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"><br>文中提到 <strong>class.phpmailer.php</strong> 是必需的,另外的文件是可选的,因为我们使用的是 SMTP,所以还需要<strong>class.smtp.php</strong>,如果你使用了 POP3,则需要引入 <strong>class.pop3.php</strong>,新建一个 Mail 文件夹,导入以上两个文件,新建 index.html,send.php,文件结构如下:<br><img src=\"http://img.blog.csdn.net/20170311165709198?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"><br>两个文件代码如下</p>\n<p>index.html<br><figure class=\"highlight html\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><!DOCTYPE html></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">html</span> <span class=\"attr\">lang</span>=<span class=\"string\">\"zh-CN\"</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">head</span>></span></div><div class=\"line\">\t<span class=\"tag\"><<span class=\"name\">meta</span> <span class=\"attr\">charset</span>=<span class=\"string\">\"UTF-8\"</span>></span></div><div class=\"line\">\t<span class=\"tag\"><<span class=\"name\">title</span>></span>phpmailer Unit Test<span class=\"tag\"></<span class=\"name\">title</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">head</span>></span></div><div class=\"line\"><span class=\"tag\"><<span class=\"name\">body</span>></span></div><div class=\"line\">\t<span class=\"tag\"><<span class=\"name\">h3</span>></span>phpmailer Unit Test<span class=\"tag\"></<span class=\"name\">h3</span>></span></div><div class=\"line\">\t请你输入<span class=\"tag\"><<span class=\"name\">font</span> <span class=\"attr\">color</span>=<span class=\"string\">\"#FF6666\"</span>></span>收信<span class=\"tag\"></<span class=\"name\">font</span>></span>的邮箱地址:</div><div class=\"line\">\t<span class=\"tag\"><<span class=\"name\">form</span> <span class=\"attr\">name</span>=<span class=\"string\">\"phpmailer\"</span> <span class=\"attr\">action</span>=<span class=\"string\">\"./send.php\"</span> <span class=\"attr\">method</span>=<span class=\"string\">\"post\"</span>></span></div><div class=\"line\">\t邮箱地址: <span class=\"tag\"><<span class=\"name\">input</span> <span class=\"attr\">type</span>=<span class=\"string\">\"text\"</span> <span class=\"attr\">size</span>=<span class=\"string\">\"50\"</span> <span class=\"attr\">name</span>=<span class=\"string\">\"address\"</span> /></span></div><div class=\"line\">\t<span class=\"tag\"><<span class=\"name\">br</span>/></span></div><div class=\"line\">\t<span class=\"tag\"><<span class=\"name\">input</span> <span class=\"attr\">type</span>=<span class=\"string\">\"submit\"</span> <span class=\"attr\">value</span>=<span class=\"string\">\"发送\"</span>/></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">form</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">body</span>></span></div><div class=\"line\"><span class=\"tag\"></<span class=\"name\">html</span>></span></div></pre></td></tr></table></figure></p>\n<p>send.php<br><figure class=\"highlight php\"><table><tr><td class=\"gutter\"><pre><div class=\"line\">1</div><div class=\"line\">2</div><div class=\"line\">3</div><div class=\"line\">4</div><div class=\"line\">5</div><div class=\"line\">6</div><div class=\"line\">7</div><div class=\"line\">8</div><div class=\"line\">9</div><div class=\"line\">10</div><div class=\"line\">11</div><div class=\"line\">12</div><div class=\"line\">13</div><div class=\"line\">14</div><div class=\"line\">15</div><div class=\"line\">16</div><div class=\"line\">17</div><div class=\"line\">18</div><div class=\"line\">19</div><div class=\"line\">20</div><div class=\"line\">21</div><div class=\"line\">22</div><div class=\"line\">23</div><div class=\"line\">24</div><div class=\"line\">25</div><div class=\"line\">26</div><div class=\"line\">27</div><div class=\"line\">28</div><div class=\"line\">29</div></pre></td><td class=\"code\"><pre><div class=\"line\"><span class=\"meta\"><?php</span></div><div class=\"line\">\t<span class=\"keyword\">require</span>(<span class=\"string\">\"class.phpmailer.php\"</span>); <span class=\"comment\">//下载的文件必须放在该文件所在目录</span></div><div class=\"line\">\t<span class=\"keyword\">require</span>(<span class=\"string\">\"class.smtp.php\"</span>);</div><div class=\"line\">\t$mail = <span class=\"keyword\">new</span> PHPMailer(); <span class=\"comment\">//建立邮件发送类</span></div><div class=\"line\">\t$address = $_POST[<span class=\"string\">'address'</span>];</div><div class=\"line\">\t$mail->IsSMTP(); <span class=\"comment\">// 使用SMTP方式发送</span></div><div class=\"line\">\t$mail->CharSet=<span class=\"string\">'UTF-8'</span>; <span class=\"comment\">// 设置邮件的字符编码</span></div><div class=\"line\">\t$mail->Host = <span class=\"string\">\"smtp.qq.com\"</span>; <span class=\"comment\">// 您的企业邮局域名</span></div><div class=\"line\">\t$mail->SMTPAuth = <span class=\"keyword\">true</span>; <span class=\"comment\">// 启用SMTP验证功能</span></div><div class=\"line\">\t$mail->SMTPSecure = <span class=\"string\">\"ssl\"</span>;</div><div class=\"line\">\t$mail->Port = <span class=\"string\">\"465\"</span>; <span class=\"comment\">//SMTP端口</span></div><div class=\"line\">\t$mail->Username = <span class=\"string\">\"[email protected]\"</span>; <span class=\"comment\">// 邮箱用户名(请填写完整的email地址)</span></div><div class=\"line\">\t$mail->Password = <span class=\"string\">\"xxx\"</span>; <span class=\"comment\">// 授权码</span></div><div class=\"line\">\t$mail->From = <span class=\"string\">\"[email protected]\"</span>; <span class=\"comment\">//邮件发送者email地址</span></div><div class=\"line\">\t$mail->FromName = <span class=\"string\">\"您的名称\"</span>;</div><div class=\"line\">\t$mail->AddAddress(<span class=\"string\">\"$address\"</span>, <span class=\"string\">\"\"</span>); <span class=\"comment\">//收件人地址(\"收件人email\",\"收件人姓名\")</span></div><div class=\"line\">\t$mail->AddReplyTo(<span class=\"string\">\"\"</span>, <span class=\"string\">\"\"</span>);</div><div class=\"line\">\t$mail->AddAttachment(<span class=\"string\">\"/var/tmp/file.tar.gz\"</span>); <span class=\"comment\">// 添加附件</span></div><div class=\"line\">\t$mail->IsHTML(<span class=\"keyword\">true</span>); <span class=\"comment\">// set email format to HTML //是否使用HTML格式</span></div><div class=\"line\">\t$mail->Subject = <span class=\"string\">\"PHPMailer测试邮件\"</span>; <span class=\"comment\">//邮件标题</span></div><div class=\"line\">\t$mail->Body = <span class=\"string\">\"Hello,这是测试邮件\"</span>; <span class=\"comment\">//邮件内容</span></div><div class=\"line\">\t$mail->AltBody = <span class=\"string\">\"This is the body in plain text for non-HTML mail clients\"</span>; <span class=\"comment\">//附加信息</span></div><div class=\"line\">\t<span class=\"keyword\">if</span>(!$mail->Send()){</div><div class=\"line\">\t\t<span class=\"keyword\">echo</span> <span class=\"string\">\"邮件发送失败. <p>\"</span>;</div><div class=\"line\">\t\t<span class=\"keyword\">echo</span> <span class=\"string\">\"错误原因: \"</span> . $mail->ErrorInfo;</div><div class=\"line\">\t\t<span class=\"keyword\">exit</span>;</div><div class=\"line\">\t}</div><div class=\"line\">\t\t<span class=\"keyword\">echo</span> <span class=\"string\">\"邮件发送成功\"</span>;</div><div class=\"line\">\t<span class=\"meta\">?></span></div></pre></td></tr></table></figure></p>\n<p>配置参数和上面的一样,不再赘述,之后点击 index.html 文件<br><img src=\"http://img.blog.csdn.net/20170312145914924?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"><br>输入邮箱地址就可以啦<br><img src=\"http://img.blog.csdn.net/20170312145935463?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"><br><img src=\"http://img.blog.csdn.net/20170312150010401?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXhpYW9mZWkxOTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast\" alt=\"这里写图片描述\"></p>\n<p><strong>以上代码均为测试,若用于生产环境,可以对其进行封装</strong><br><strong>如有问题,欢迎回复交流</strong><br><br><br></p>\n","categories":["后端"],"tags":["PHP"]},{"title":"关于本博客","url":"http://mrzhouxiaofei.com/2017/01/05/关于本博客/","content":"<h1 id=\"关于本博客\"><a href=\"#关于本博客\" class=\"headerlink\" title=\"关于本博客\"></a>关于本博客</h1><p>想要搭建自己的个人博客也有一段时间了,之前考核做了个人博客,后来买空间,买域名,把例子也放了上去,但那个做的实在粗糙,拿不出手,放上去一段时间,就撤下来了。</p>\n<p>之前重写博客,但是没有做好规划,后端写了一部分,去写前端,发现页面写的太丑,对于一个追求完美的人来说,真的不能接受,如此,就搁置了一段时间。而且我搭建个人博客的初衷是记录自己的学习和生活,当然如果能对别人有一些帮助,那就更好了,一直在搭建博客上钻研,这就显得本末倒置了。</p>\n<p>后来几个小伙伴用 <strong>WordPress</strong> 搭建了博客,看着效果还不错,就去试用了一段时间,不过越用越感觉它太重了,很多的功能都用不到,我只是想安安静静的写博客啊。无奈,放弃。</p>\n<p>经常在网上搜索问题,也常看别人的博客,发现很多人的博客都放在 <strong>GitHub</strong> 上,效果很好,页面也很简洁。了解一下,知道了 <strong>GitHub Pages</strong>,顿时感觉这就是我想要的,马上摸索,又知道了博客搭建工具 <strong>Hexo</strong>, 然后很快搭建了自己的博客。</p>\n<p>使用 <strong>Hexo</strong> 最大的好处,就是你不用去关注太多东西,只需专注博客的内容就好了,简单配置下,就可以使用,而且不用像之前一样去买云服务器。如果感觉不喜欢 <strong>username.github.io</strong> ,买个逼格高的域名解析一下就行了。</p>\n<p>另外,<strong>Hexo</strong> 提供了很多主题,如果不喜欢,随时可以换。秉持着 <strong>Simple is the best</strong> 的原则,选择了现在的主题,喜欢的,可以在这里 <a href=\"https://github.com/forsigner/fexo\" target=\"_blank\" rel=\"external\">forsigner</a> 找到主题原作者。 </p>\n<p>博客搭建完成了,以后的博客都会同步更新到这里,欢迎交流!<br><br><br></p>\n","categories":["随笔"],"tags":["随笔"]},{"title":"about","url":"http://mrzhouxiaofei.com/about/index.html","content":"","categories":[],"tags":[]},{"title":"category","url":"http://mrzhouxiaofei.com/category/index.html","content":"","categories":[],"tags":[]},{"title":"search","url":"http://mrzhouxiaofei.com/search/index.html","content":"","categories":[],"tags":[]},{"title":"tag","url":"http://mrzhouxiaofei.com/tag/index.html","content":"","categories":[],"tags":[]}]