当前位置:首页 > 程序设计 > PHP开发电子书网盘下载
PHP开发实例大全:提高卷 PHP开发实例大全:提高卷
bd_jc

bd_jc 提供上传

资源
35
粉丝
22
喜欢
262
评论
14

    PHP开发实例大全:提高卷 PDF 高清影印版

    PHP开发电子书
    • 发布时间:

    给大家带来的一篇关于PHP开发相关的电子书资源,介绍了关于PHP开发、PHP实例大全方面的内容,本书是由清华大学出版社出版,格式为PDF,资源大小241.1 MB,软件开发技术联盟编写,目前豆瓣、亚马逊、当当、京东等电子书综合评分为:8.9,更多相关的学习资源可以参阅javascript库Web测试Java讲义图片压缩qcril、等栏目。

  • PHP开发实例大全:提高卷 PDF 下载
  • 下载地址:https://pan.baidu.com/s/1Jld8fKpwbMDGwXquBBjAS
  • 提取码:42u4
  • 读者评价

    这本《PHP开发实例大全(提高卷)》里面有很多PHP开发的实际案例,字体非常小,书非常厚,相信读完(基础卷)再来看这本(提高卷),一定能建成非常实用和美观的网站。

    明日的1200例题下册,上册是名声在外,相信学php的都略有耳闻。本书不愧是提高版,适合中高层次人员。看目录有一半都是初学者不曾见识的名称。或许工作了一两年再回来看会觉得得心应手吧。本书还有jq,ajax等前端内容,所以说,前端早晚都还得学

    内容丰富,讲解清晰,就是内容太多,有视频,不多,主要以文字讲解为主,需要花的时间比较多,讲解的编程心得比较多,适合初学者慢慢雕琢

    这本《PHP开发实例大全(提高卷)》从一个个典型的模块出发,逐一讲解网站的建设编程中会遇到的问题,相当的经典。

    这本《PHP开发实例大全(提高卷)》里面从PHP、MySQL软件的安装开始,都是拆分成一个个具体的小实例,非常的不错。相应读完这本基础卷一定能开发出比较像样的网站来。

    筛选、汇集了PHP开发从基础知识到高级应用各个层面的大量实例及源代码,共有600个左右,每个实例及源代码按实例说明、关键技术、设计过程、详尽注释、秘笈心法的顺序进行了分析解读。

    编辑评价

    多读源码,可以快速学习!多读源码,可以提高熟练度!
    实例案例,拿来就用,效率可提高N倍!
    《php开发实例大全》超级详尽的实例大全,源码分析的案头手册,提高效率的绝好帮手!
    40个方向,1225个实例案例,php编程类四库全书,分门别类常用编程实例,一网打尽!
    实例说明、技术要点、代码实现、详尽注释、秘籍心法,条分缕析代码实现过程!
    《php开发实战1200例》之全新升级!

    内容介绍

    《PHP开发实例大全(提高卷)》以开发人员在项目开发中经常遇到的问题和必须掌握的技术为中心,介绍了应用PHP进行Web开发的各个方面的知识和技巧,主要包括PHP与Ming扩展库,PHP与ImageMagick图片处理,AJAX无刷新技术,jQuery框架技术,PHP与在线编辑工具,PHP与多媒体技术,PHP与FPDF类库应用,报表与打印技术,网络、服务与服务器,邮件处理技术,XML操作技术,Web服务器与远程过程调用,LDAP(轻量级目录访问协议),PHP与WAP技术,PHP与FTP,PostgreSQL数据库,SQLite数据库,PDO数据库抽象层,PHPLib数据库抽象层,网站策略与安全,PHP调试、升级与优化,ThinkPHP框架,Zend Framework框架,明日导航网(ThinkPHP),明日搜索引擎(Zend Framework)等内容。配书光盘附带了实例的完整源程序。

    《PHP开发实例大全(提高卷)》既适合PHP程序员参考和查阅,也适合PHP初学者,如高校学生、软件开发培训学员及相关求职人员学习、练习、速查使用。

    内容节选

    关键技术

    本实例首先创建了一个SWFFont字体对象,然后创建一个SWFTextField文本区域对象,将SWFFont对象通过setFont()方法赋予SWFTextField对象,其语法如下:

    void setFont(SWFFont $font)

    参数说明

    $font:SWFFont类的对象,用来设置字体。

    然后设置文本区域的颜色、高度、文本内容。其中用到了SWFTextField 类的setColor()方法和addString()方法,setColor()方法的颜色值用的是RGB颜色,语法如下:

    void setColor(int $red,int $green,int $blue[,int $a=255])

    参数说明

    $red:红色通道的颜色。

    $green:绿色通道的颜色。

    $blue:蓝色通道的颜色。

    $a:可选参数,阿尔法通道的颜色,默认值为255。

    addString()方法用于设置文本域要显示的文字,语法如下:

    void addString (string $string)

    参数说明

    $string:要添加的字符串值。

    字体设置完毕后,创建一个SWFMovie类的对象,代表即将生成的Flash动画,将这个文本区域添加至动画中。其中SWFMovie类的setDimension()方法用来设置Flash动画的宽度和高度,add()方法用来给动画添加数据。语法如下:

    mixed add (object $instance)

    参数说明

    $instance:SWF对象,类型可以是SWFFont、SWFText和SWFShape等。

    返回值:对于可显示的类型(shape,text,button,sprite),返回值是一个SWFDisplayItem对象,指向显示列表对象的句柄。

    output()方法负责将动画直接在浏览器显示,而不用生成SWF文件。需要注意的是,使用这个方法之前,需要发送HTTP头文件,指定Content-Type类型。

    设计过程

    (1)创建一个PHP脚本文件,命名为index.php,存储于MR\01\002下。

    (2)程序主要代码如下:

    <?php
    $font = new SWFFont('_sans');          //创建SWFFont类对象,字体为无衬线类型
    $text = new SWFTextField();              //创建SWFTextField类对象
    $text->setFont($font);                   //设置字体
    $text->setColor(0,0,0);                  //设置颜色
    $text->setHeight(100);                   //设置高度
    $text->addString('吉林省明日科技');      //设置文本域的文字内容
    $movie = new SWFMovie();               //创建SWFMovie类对象
    $movie->setDimension(1500,800);          //设置movie的宽度和高度
    $movie->add($text);                      //将text对象添加到movie中
    header("Content-Type:application/x-shockwave-flash");
    $movie->output();   

    作者简介

    作者系一家以计算机软件开发和教育为核心的高科技企业和一些中青年骨干教师组成松散组织,专门从事应用软件开发与服务,涉及的软件行业有煤矿、公交、物流、办公系统、零售、生产等多种领域。该组织近年来参与的图书有《软件开发视频大讲堂》、《软件开发全程实录》等多个系列,5种图书荣获“全行业优秀畅销书”奖,3种荣获出版社“优秀畅销书(专业类)“奖,14种版权输出到台湾等地,为IT教育培训做出了积极贡献。

    目录

    • 第1篇 Web应用篇
    • 第1章 PHP与Ming扩展库
    • 1.1 Ming扩展库基本应用
    • 实例001 加载Ming扩展库
    • 实例002 静态输出“吉林省明日科技”
    • 实例003 动态输出“明日科技欢迎您”
    • 1.2 Ming扩展绘制线段
    • 实例004 绘制一条直线
    • 实例005 绘制一条曲线
    • 实例006 绘制一条旋转直线
    • 1.3 Ming扩展绘制图形
    • 实例007 绘制一个圆
    • 实例008 绘制一个正方形
    • 实例009 控制图片的渐变输出
    • 实例010 控制图片向上移动
    • 实例011 控制图片向下移动
    • 实例012 控制图片的旋转
    • 实例013 创建一个按钮并添加事件
    • 第2章 PHP与ImageMagick图片处理
    • 2.1 ImageMagick处理图片
    • 实例014 下载、安装ImageMagick
    • 实例015 判断指定图片是否存在
    • 实例016 获取图片信息
    • 实例017 裁剪指定的图片
    • 实例018 将图片由PNG格式转换为JPG格式
    • 实例019 对JPG格式的图片进行压缩
    • 2.2 ImageMagick应用
    • 实例020 控制图片45°旋转
    • 实例021 绘制图片的缩略图
    • 实例022 为图片添加旋涡效果
    • 实例023 按照原始比例缩放图片
    • 实例024 制作个人画册
    • 第3章 AJAX无刷新技术
    • 3.1 AJAX操作图像
    • 实例025 AJAX无刷新图像上传
    • 实例026 AJAX无刷新输出上传图像
    • 实例027 AJAX无刷新载入图像
    • 实例028 AJAX动态生成缩略图
    • 3.2 AJAX控制表单
    • 实例029 AJAX检测用户名是否被占用
    • 实例030 AJAX无刷新下拉列表
    • 实例031 AJAX无刷新级联下拉列表
    • 实例032 AJAX验证用户注册信息
    • 实例033 AJAX无刷新添加数据信息
    • 3.3 AJAX操作XML
    • 实例034 AJAX无刷新读取XML文件
    • 实例035 AJAX读取XML节点属性
    • 3.4 AJAX实战应用
    • 实例036 AJAX读取HTML文件
    • 实例037 AJAX添加图书信息
    • 实例038 AJAX查询图书信息
    • 实例039 AJAX修改图书信息
    • 实例040 AJAX删除图书信息
    • 实例041 AJAX无刷新分页
    • 实例042 AJAX实现博客文章类别添加
    • 实例043 AJAX实现用户登录
    • 实例044 AJAX无刷新查询数据
    • 实例045 AJAX无刷新倒计时
    • 实例046 AJAX无刷新显示聊天信息
    • 实例047 AJAX无刷新显示公告信息
    • 实例048 AJAX无刷新获取用户的个人信息
    • 实例049 AJAX无刷新获取新闻内容
    • 实例050 AJAX获取指定图书信息
    • 第4章 jQuery框架技术
    • 4.1 网页特效
    • 实例051 jQuery实现查找节点
    • 实例052 图片幻灯片
    • 实例053 颜色拾取器
    • 实例054 广告轮显
    • 实例055 图片放大镜
    • 实例056 jQuery幕帘效果
    • 实例057 jQuery动态变化的数字
    • 实例058 jQuery淡入淡出动画效果
    • 实例059 jQuery上下卷帘动画效果
    • 实例060 自动隐藏式菜单
    • 实例061 图片传送带
    • 实例062 打造自己的开心农场
    • 4.2 jQuery操作表单
    • 实例063 检测用户名是否被占用
    • 实例064 jQuery验证表单元素
    • 实例065 密码强度检测
    • 实例066 文本框提示标签
    • 实例067 文本编辑器
    • 实例068 右键菜单
    • 实例069 jQuery二级联动下拉列表框
    • 实例070 jQuery三级联动下拉列表框
    • 实例071 复选框的全选、反选和全不选
    • 实例072 表单动态变色
    • 实例073 上传图片预览
    • 实例074 通过下拉列表选择头像
    • 4.3 jQuery操作表格
    • 实例075 jQuery横向导航
    • 实例076 jQuery竖向导航
    • 实例077 jQuery弹出层
    • 实例078 jQuery滑动门
    • 实例079 jQuery可编辑表格
    • 实例080 jQuery实现表格隔行变色
    • 实例081 jQuery拖曳
    • 实例082 jQuery翻滚的消息动态
    • 实例083 jQuery动态换肤
    • 实例084 可展开和关闭的表格
    • 实例085 单行左右移动的消息提示
    • 实例086 显示全部资源与精简资源
    • 4.4 jQuery与Jpgraph结合
    • 实例087 jQuery与Jpgraph动态制作折线图分析网站访问量
    • 实例088 jQuery与GD2函数制作验证码
    • 4.5 jQuery操作XML
    • 实例089 通过jQuery读取XML文件
    • 第5章 PHP与在线编辑工具
    • 5.1 常用在线编辑器
    • 实例090 自定义在线编辑器
    • 实例091 在博客中应用自定义在线编辑器
    • 5.2 FCKeditor在线编辑器
    • 实例092 CKEditor网页编辑器
    • 实例093 将CKEditor网页编辑器嵌入到后台管理系统中
    • 实例094 FCKeditor文本编辑器
    • 实例095 在论坛的帖子回复中应用FCKeditor
    • 第6章 PHP与多媒体技术
    • 6.1 操控音频文件
    • 实例096 在线音乐上传
    • 实例097 在线音乐下载
    • 实例098 MP3在线点播
    • 实例099 MP3下载
    • 实例100 创建.m3u格式的文件
    • 实例101 无刷新删除.m3u格式的文件
    • 实例102 通过object标签向HTML页中载入多媒体
    • 实例103 通过embed标签向HTML页中载入多媒体
    • 实例104 歌词的同步输出
    • 实例105 在线播放列表
    • 实例106 在线音乐的循环播放
    • 实例107 在线音乐的连续播放
    • 实例108 收藏其他网站的音乐
    • 6.2 操控影音文件
    • 实例109 通过RealPlayer播放器播放视频文件
    • 实例110 通过Media Player播放器播放视频文件
    • 实例111 控制播放器窗口的状态
    • 实例112 播放FLV视频文件
    • 实例113 在网页中加入可控的背景音乐
    • 实例114 在博客中加入可控的背景音乐
    • 6.3 操控Flash动画文件
    • 实例115 在网页中嵌入Flash
    • 实例116 在网页中嵌入背景透明的Flash
    • 实例117 向Flash中传递参数
    • 实例118 嵌入Flash播放器
    • 实例119 用JavaScript控制Flash
    • 第7章 PHP与FPDF类库应用
    • 7.1 编辑、设计PDF文档
    • 实例120 配置FPDF
    • 实例121 创建FPDF文档
    • 实例122 下载PDF文档
    • 实例123 向PDF中插入图片
    • 实例124 为FPDF增加中文支持
    • 实例125 设置FPDF的页眉和页脚
    • 实例126 通过FPDF绘制表格
    • 7.2 PDF文档的实战应用
    • 实例127 设计编程词典说明书的PDF文档
    • 实例128 设计编程词典产品介绍的PDF文档
    • 实例129 设计编程词典安装说明的PDF文档
    • 实例130 动态生成编程词典注册用户的PDF文档
    • 实例131 设计毕业论文的PDF文档
    • 第8章 报表与打印技术
    • 8.1 操作Word
    • 实例132 将数据库数据保存到Word
    • 实例133 将查询结果保存到Word
    • 实例134 将Web页中的表格导出到Word并打印
    • 实例135 打开指定的Word文档并打印
    • 实例136 调用Word自动打印指定格式的会议记录
    • 8.2 操作Excel
    • 实例137 将MySQL数据表中的数据导出到Excel
    • 实例138 将查询结果导出到Excel
    • 实例139 将Web页面中的数据导出到Excel
    • 实例140 将Web页面中的数据导出到Excel并自动打印
    • 实例141 将Excel中的数据导出到MySQL数据库
    • 实例142 将Excel中的工资数据导入到SQL Server数据库
    • 实例143 将SQL Server数据导出到Excel
    • 8.3 报表打印
    • 实例144 调用IE自身的打印功能实现打印
    • 实例145 打印指定框架中的内容
    • 实例146 使用WebBrowser打印报表
    • 实例147 设置页眉页脚
    • 实例148 利用CSS样式打印页面中的指定内容
    • 实例149 利用CSS样式实现分页打印
    • 8.4 报表打印实战应用
    • 实例150 打印汇款单
    • 实例151 打印快递单
    • 实例152 打印信封
    • 实例153 GD2函数动态生成图表并打印
    • 实例154 打印用户的通讯记录
    • 实例155 JavaScript脚本打印账单
    • 实例156 打印工资条
    •  
    • 第2篇 网络应用篇
    • 第9章 网络、服务与服务器
    • 9.1 获取服务器信息
    • 实例157 根据IP地址获取主机名称
    • 实例158 根据主机名称获取IP地址
    • 实例159 获取主机的所有IP地址
    • 实例160 将IP地址转换为整数
    • 实例161 将整数型IP地址还原为4个圆点分隔形式
    • 9.2 Socket实现“C/S”通信
    • 实例162 创建Socket服务器
    • 实例163 创建Socket客户端
    • 实例164 通过Socket发送短信
    • 实例165 短信群发
    • 9.3 常见网络任务
    • 实例166 验证服务器是否连接
    • 实例167 开发端口扫描器
    • 实例168 利用curl获取HTML内容
    • 实例169 利用curl模拟POST方式发送数据
    • 实例170 curl批处理
    • 第10章 邮件处理技术
    • 10.1 配置服务器
    • 实例171 SMTP和POP3服务器的安装与配置
    • 实例172 Winmail服务器的安装与配置
    • 实例173 通过mail()函数发送邮件
    • 10.2 通过imap电子邮件系统函数操作邮件
    • 实例174 登录邮件服务器
    • 实例175 接收邮件
    • 实例176 浏览邮件
    • 实例177 下载附件
    • 实例178 查找邮件
    • 实例179 发送邮件
    • 实例180 发送带附件的邮件
    • 实例181 邮件群发
    • 实例182 删除邮件
    • 10.3 使用Zend_Mail组件发送邮件
    • 实例183 Zend_Mail组件发送普通文本邮件
    • 实例184 Zend_Mail组件发送HTML格式文本邮件
    • 实例185 Zend_Mail组件发送附件
    • 实例186 Zend_Mail组件发送群邮件
    • 实例187 Zend_Mail组件接收邮件
    • 实例188 Zend_Mail组件获取邮件内容
    • 第11章 XML操作技术
    • 11.1 创建XML文件
    • 实例189 手动创建XML文件
    • 实例190 在PHP中创建XML文件
    • 实例191 通过文件系统函数创建XML文件
    • 实例192 通过DOM创建XML文件
    • 实例193 读取XML文件
    • 11.2 XML文件节点操作
    • 实例194 插入XML节点
    • 实例195 修改XML节点
    • 实例196 删除XML节点
    • 11.3 XML文件转换
    • 实例197 在HTML页面中使用XML文件
    • 实例198 在XML文件中应用CSS样式
    • 实例199 XSL转换XML文件
    • 11.4 SimpleXML函数操作XML
    • 实例200 遍历所有子节点
    • 实例201 遍历所有属性
    • 实例202 访问特定节点元素和属性
    • 实例203 修改并保存XML文档
    • 11.5 动态操作XML
    • 实例204 PHP动态创建XML文档
    • 实例205 PHP动态添加XML数据
    • 实例206 PHP动态查询XML数据
    • 实例207 PHP动态修改XML数据
    • 实例208 PHP动态删除XML数据
    • 11.6 XML实战应用―留言板
    • 实例209 用户注册
    • 实例210 用户登录
    • 实例211 发布留言
    • 实例212 浏览留言
    • 实例213 编辑留言
    • 实例214 删除留言
    • 11.7 XML实战应用―RSS阅读器
    • 实例215 创建支持RSS阅读的站点
    • 实例216 动态创建RSS文件
    • 实例217 创建RSS阅读器的框架
    • 实例218 添加频道组
    • 实例219 删除频道组
    • 实例220 添加频道
    • 实例221 删除频道
    • 实例222 树状导航菜单输出频道组和频道
    • 实例223 AJAX无刷新读取订阅信息
    • 第12章 Web服务器与远程过程调用
    • 12.1 SOAP扩展
    • 实例224 Windows下安装、配置SOAP
    • 实例225 建立SOAP服务器端
    • 实例226 建立SOAP客户端
    • 12.2 PHP与Web Service的交互操作
    • 实例227 NuSOAP类库的安装、配置
    • 实例228 PHP创建Web Service
    • 实例229 PHP访问Web Service
    • 实例230 PHP通过Web Service发送短信
    • 12.3 XML-RPC(远程过程调用)
    • 实例231 客户端请求的XML格式
    • 实例232 服务器响应的XML格式
    • 实例233 错误信息的XML格式
    • 实例234 XML-RPC的综合应用―数学运算
    • 第13章 LDAP(轻量级目录访问协议)
    • 13.1 LDAP服务器的安装与配置
    • 实例235 安装LDAP服务器
    • 实例236 配置LDAP服务器
    • 实例237 OpenLDAP的启动和关闭
    • 13.2 通过命令操作LDAP服务器
    • 实例238 通过命令向OpenLDAP服务器中添加数据
    • 实例239 通过命令查询OpenLDAP服务器中的数据
    • 13.3 phpLDAPadmin图形工具简介
    • 实例240 下载安装phpLDAPadmin工具
    • 13.4 PHP操作LDAP服务器
    • 实例241 在PHP中加载LDAP
    • 实例242 连接、绑定和断开LDAP服务器
    • 实例243 查询LDAP目录的内容
    • 实例244 获取查询结果中的值
    • 实例245 统计查询结果的记录数
    • 实例246 向LDAP中添加记录
    • 实例247 更新LDAP中的记录
    • 实例248 删除LDAP中的记录
    • 实例249 获取错误处理信息
    • 实例250 LDAP服务器实战应用―验证用户身份
    • 第14章 PHP与WAP技术
    • 14.1 配置WAP
    • 实例251 Apache中配置WAP
    • 实例252 制作**个WAP页面
    • 实例253 WAP页面跳转
    • 14.2 WAP的应用
    • 实例254 动态生成图像
    • 实例255 使用WAP获取下拉列表框选项内容
    • 实例256 使用WAP制作用户注册页面
    • 实例257 站内查询功能
    • 实例258 使用WAP制作用户登录页面
    • 14.3 Smarty与WAP
    • 实例259 通过if语句判断当前用户的权限
    • 实例260 通过foreach语句读取数组中的数据
    • 实例261 Smarty模板中生成数字验证码
    • 实例262 通过html_options()函数向下拉列表框中添加列表项
    • 实例263 在模板文件中定义CSS样式
    • 实例264 通过section循环输出数据
    • 实例265 Smarty实现数据库信息分页显示
    • 实例266 Smarty模板中时间的格式化输出
    • 实例267 Smarty模板中的编码
    • 实例268 Smarty模板中应用正则表达式
    • 实例269 Smarty模板中的关键字描红技术
    • 实例270 Smarty模板中控制输出字符串的行宽
    • 实例271 Smarty模板中自定义创建form表单
    • 实例272 register_function()方法注册模板函数
    • 实例273 register_object ()方法注册模板对象
    • 实例274 在Smarty中通过truncate方法截取字符串
    • 实例275 Smarty模板制作用户注册页面
    • 实例276 Smarty模板制作后台管理系统主页
    • 实例277 Smarty模板页嵌入PHP脚本
    • 实例278 在模板中包含子模板
    • 实例279 为网站的首页开启缓存
    • 实例280 开启网站注册页面的缓存
    • 实例281 通过配置文件定义变量
    • 第15章 PHP与FTP
    • 15.1 安装、配置服务器端软件
    • 实例282 安装、配置Serv-U
    • 实例283 连接、关闭FTP服务器
    • 15.2 操作FTP服务器
    • 实例284 上传文件到FTP服务器
    • 实例285 从FTP服务器中下载文件
    • 实例286 更改FTP服务器中的文件名称
    • 实例287 删除FTP服务器中的指定文件
    • 实例288 在FTP服务器中创建目录
    • 实例289 遍历FTP服务器指定目录下的文件
    • 实例290 文件批量上传到FTP服务器
    • 实例291 将指定类型的文件上传到FTP服务器
    • 实例292 将FTP服务器中的文件批量下载到本地
    • 实例293 将指定类型的文件下载到本地计算机
    • 实例294 查看FTP服务器指定子目录下的详细信息
    • 第3篇 数据库与抽象层篇
    • 第16章 PostgreSQL数据库
    • 16.1 PostgreSQL数据库的安装与操作
    • 实例295 PostgreSQL数据库安装
    • 实例296 PostgreSQL服务的启动与停止
    • 实例297 启动pgAdmin III工具
    • 实例298 连接PostgreSQL服务器
    • 16.2 通过pgAdminIII操作PostgreSQL数据库
    • 实例299 创建database16数据库
    • 实例300 创建tb_book数据库表
    • 实例301 向tb_book表中添加数据
    • 实例302 在pgAdminIII中通过SQL语句查询tb_book表中数据
    • 16.3 PHP操作PostgreSQL数据库
    • 实例303 在PHP中加载PostgreSQL函数库
    • 实例304 连接、关闭PostgreSQL数据库
    • 实例305 pg_query()函数执行SQL语句
    • 实例306 pg_num_rows()函数获取查询结果集的记录数
    • 实例307 pg_fetch_array()函数将结果集返回到数组
    • 实例308 pg_fetch_row()函数从结果集中获取一行作为枚举数组
    • 实例309 pg_fetch_assoc()函数返回关联数组
    • 实例310 pg_insert()函数添加图书信息
    • 实例311 select语句查询图书信息
    • 实例312 分页显示图书信息
    • 实例313 pg_update()函数更新图书信息
    • 实例314 图书名称的批量更新
    • 实例315 pg_delete()函数删除图书信息
    • 实例316 图书信息的批量删除
    • (删除前给出提示信息)
    • 第17章 SQLite数据库
    • 17.1 SQLite数据库的安装与配置
    • 实例317 下载安装SQLite数据库
    • 实例318 配置SQLite数据库
    • 17.2 SQLite数据库的操作
    • 实例319 创建database17数据库
    • 实例320 查看database17数据库
    • 实例321 创建tb_user数据表
    • 实例322 查看tb_user数据表
    • 实例323 向tb_user数据库表中添加数据
    • 实例324 查看tb_user数据表中的数据
    • 17.3 PHP操作SQLite数据库
    • 实例325 连接、关闭数据库
    • 实例326 query()方法执行SQL语句
    • 实例327 fetchArray()方法返回数组结果行
    • 实例328 获取查询结果集的记录数
    • 实例329 获取结果集列数
    • 实例330 reset()方法返回**行数据
    • 实例331 获取*近插入数据的ID值
    • 实例332 返回数据库受影响行数
    • 实例333 prepare预查询语句
    • 实例334 添加用户注册信息
    • 实例335 用户登录
    • 实例336 查询注册用户
    • 实例337 分页显示注册用户信息
    • 实例338 显示用户信息按照ID排序
    • 实例339 修改用户注册信息
    • 实例340 删除注册用户
    • 第18章 PDO数据库抽象层
    • 18.1 PDO安装、配置
    • 实例341 Windows下安装PDO
    • 实例342 Linux下安装PDO
    • 18.2 PDO连接数据库
    • 实例343 PDO连接MySQL数据库
    • 实例344 PDO连接SQL Server 2000数据库
    • 实例345 PDO连接Access数据库
    • 实例346 PDO连接Oracle数据库
    • 实例347 PDO连接PostgreSQL数据库
    • 实例348 PDO连接SQLite数据库
    • 18.3 PDO查询
    • 实例349 向图书信息表中添加数据
    • 实例350 修改图书表中的数据
    • 实例351 删除图书信息表中的指定数据
    • 实例352 删除图书信息表中的所有数据
    • 实例353 查询字符串
    • 实例354 查询日期型数据
    • 实例355 查询逻辑型数据
    • 实例356 查询非空数据
    • 实例357 利用变量查询字符串数据
    • 实例358 利用变量查询数值型数据
    • 实例359 查询指定的N条记录
    • 实例360 查询前N条记录
    • 实例361 查询后N条记录
    • 实例362 查询从指定位置开始的N条记录
    • 实例363 查询统计结果中的前N条记录
    • 实例364 查询指定时间段的数据
    • 实例365 按月查询统计数据
    • 实例366 查询大于指定条件的记录
    • 实例367 查询结果不显示重复记录
    • 实例368 NOT与谓词进行组合条件的查询
    • 实例369 显示数据表中的重复记录和记录条数
    • 实例370 对数据进行降序查询
    • 实例371 对数据进行多条件排序
    • 实例372 对统计结果进行排序
    • 实例373 单列数据分组统计
    • 实例374 多列数据分组统计
    • 实例375 多表分组统计
    • 实例376 使用聚集函数sum()对学生成绩进行汇总
    • 实例377 使用聚集函数avg()求平均每月的图书销量
    • 实例378 使用聚集函数min()求销售额、利润*少的商品
    • 实例379 使用聚集函数max()求月销售额完成*多的销售记录
    • 实例380 使用聚集函数count()求日销售额大于某值的记录数
    • 实例381 使用聚集函数first(或last)求数据表中**条或*后一条记录
    • 实例382 使用from子句进行多表查询
    • 实例383 使用表的别名
    • 实例384 合并多个结果集
    • 实例385 简单的嵌套查询
    • 实例386 复杂的嵌套查询
    • 实例387 复杂嵌套查询在查询统计中的应用
    • 实例388 使用子查询作派生的表
    • 实例389 使用子查询作表达式
    • 实例390 使用子查询关联数据
    • 实例391 多表联合查询
    • 实例392 对联合查询后的结果进行排序
    • 实例393 条件联合语句
    • 实例394 简单内连接查询
    • 实例395 复杂内连接查询
    • 实例396 两表的内连接关联
    • 实例397 使用外连接进行多表联合查询
    • 实例398 left outer join查询
    • 实例399 right outer join查询
    • 实例400 利用in或notin语句限定范围
    • 实例401 用in查询表中的记录信息
    • 实例402 由in引入的关联子查询
    • 实例403 利用transform分析数据
    • 实例404 利用transform统计数据
    • 实例405 使用格式化函数转换查询条件的数据类型
    • 实例406 在查询中使用字符串函数
    • 实例407 在查询中使用日期函数
    • 实例408 利用having语句过滤分组数据
    • 18.4 PDO错误处理
    • 实例409 获得查询错误号
    • 实例410 获得查询错误信息
    • 实例411 在PDO中设置错误模式
    • 实例412 通过异常处理捕获PDO异常信息
    • 实例413 使用函数die()打印错误信息
    • 18.5 PDO事务
    • 实例414 执行一个批处理事务
    • 实例415 实现银行安全转账
    • 实例416 多表数据同时安全删除
    • 实例417 通过事务处理方式保存数据
    • 实例418 通过事务处理方式更新数据
    • 18.6 PDO存储过程
    • 实例419 通过存储过程实现用户注册
    • 实例420 通过存储过程实现用户登录
    • 实例421 通过存储过程删除注册用户
    • 实例422 通过存储过程修改学生信息
    • 第19章 PHPLib数据库抽象层
    • 19.1 PHPLib下载、安装
    • 实例423 下载PHPLib
    • 实例424 使用require语句导入PHPLib类库
    • 实例425 自动加载PHPLib类库文件
    • 19.2 PHPLib操作MySQL数据库
    • 实例426 向产品信息表中添加数据
    • 实例427 修改产品信息表中的数据
    • 实例428 删除产品信息表中的指定数据
    • 实例429 删除商品信息表中的所有数据
    • 实例430 查询字符串
    • 实例431 查询日期型数据
    • 实例432 查询逻辑型数据
    • 实例433 查询非空数据
    • 实例434 利用变量查询字符串数据
    • 实例435 利用变量查询数值型数据
    • 实例436 查询指定的N条记录
    • 实例437 查询前N条记录
    • 实例438 查询后N条记录
    • 实例439 查询从指定位置开始的N条记录
    • 实例440 查询统计结果中的前N条记录
    • 实例441 查询指定时间段的数据
    • 实例442 分页查询
    • 19.3 PHPLib操作Oracle数据库
    • 实例443 添加留言信息
    • 实例444 修改留言信息
    • 实例445 删除留言信息
    • 实例446 留言信息分页输出
    • 实例447 查询留言信息
    • 第4篇 网站安全与优化篇
    • 第20章 网站策略与安全
    • 20.1 文件保护
    • 实例448 防止用户直接输入地址访问PHP文件
    • 实例449 防止页面重复提交
    • 实例450 对查询字符串进行URL编码
    • 实例451 过滤HTML非法字符
    • 实例452 禁止用户输入敏感字符
    • 20.2 漏洞防护
    • 实例453 防止Access数据库被下载
    • 实例454 操作带密码的Access数据库
    • 实例455 越过表单限制漏洞
    • 实例456 文件上传漏洞
    • 实例457 隐藏PHP文件扩展名
    • 实例458 通过邮箱激活注册用户
    • 实例459 本地文件包含漏洞
    • 实例460 远程文件包含漏洞
    • 实例461 检测文件上传类型
    • 实例462 SQL注入漏洞
    • 20.3 数据加密
    • 实例463 通过base64对数据库进行编码
    • 实例464 以RFC1738规则对URL进行编码
    • 实例465 禁止复制和另存为网页内容
    • 实例466 通过MD5对用户密码进行加密
    • 实例467 使用crypt()函数对用户注册密码进行加密
    • 实例468 使用sha1()函数对用户注册密码进行加密
    • 实例469 使用Mcrypt扩展库对用户注册密码进行加密
    • 实例470 通过Mhash扩展库对用户注册密码进行加密
    • 20.4 身份验证
    • 实例471 直接对用户的身份进行验证
    • 实例472 通过文本文件对用户身份进行验证
    • 实例473 验证码登录技术
    • 实例474 通过数据库完成身份的验证
    • 实例475 通过IP验证用户身份
    • 实例476 为注册用户生成随机密码
    • 第21章 PHP调试、升级与优化
    • 21.1 错误类型举例
    • 实例477 语法错误
    • 实例478 定义错误
    • 实例479 逻辑错误
    • 实例480 运行错误
    • 实例481 环境错误
    • 21.2 程序调试方法
    • 实例482 应用die()语句调试
    • 实例483 应用mysql_error()语句输出错误信息
    • 实例484 应用try{}catch{}语句抛出并捕获异常
    • 21.3 错误处理技巧
    • 实例485 隐藏错误
    • 实例486 自定义错误页面
    • 实例487 延长服务器执行时间―处理超时错误
    • 实例488 如何分析、解决PHP与MySQL连接错误
    • 实例489 解决数据库乱码问题
    • 实例490 封装属于自己的异常处理类
    • 实例491 使用错误处理器记录日志
    • 实例492 通过mysql_error()函数调试SQL语句中的错误
    • 实例493 通过phpMyAdmin调试SQL语句中的错误
    • 21.4 PHP优化技巧
    • 实例494 PHP脚本级优化
    • 实例495 使用代码优化工具
    • 实例496 使用代码优化工具
    • 实例497 MySQL日志维护
    • 实例498 Apache服务器优化
    • 实例499 内容压缩与优化
    • 21.5 常见的程序漏洞和防护
    • 实例500 允许用户设置全局变量漏洞
    • 实例501 文件上传漏洞
    • 实例502 根据错误信息攻击服务器漏洞
    • 实例503 远程文件包含漏洞
    • 实例504 SQL注入漏洞
    • 第5篇 框架与项目整合篇
    • 第22章 ThinkPHP框架
    • 22.1 ThinkPHP的MVC环境搭建
    • 实例505 环境配置
    • 实例506 框架结构
    • 实例507 创建流程
    • 22.2 ThinkPHP的MVC操作
    • 实例508 URL访问
    • 实例509 ThinkPHP控制器
    • 实例510 ThinkPHP视图
    • 实例511 ThinkPHP模型
    • 22.3 ThinkPHP的访问数据库操作
    • 实例512 连接MySQL数据库
    • 实例513 用户注册
    • 实例514 用户登录
    • 实例515 发布信息
    • 实例516 查询信息
    • 实例517 修改信息
    • 实例518 删除信息
    • 实例519 信息分页显示
    • 第23章 Zend Framework框架
    • 23.1 Zend Framework的MVC环境搭建
    • 实例520 环境配置
    • 实例521 框架结构
    • 实例522 创建流程
    • 实例523 Zend Framework的编码标准
    • 23.2 Zend_Layout网站布局
    • 实例524 Zend_Layout对站点进行布局
    • 实例525 通过Zend_Layout对新闻页面进行布局
    • 23.3 Zend_Config配置文件
    • 实例526 Zend_Config配置站点初始参数
    • 23.4 Zend_Cache缓存服务
    • 实例527 Zend_Cache对数据库中的信息缓存输出
    • 实例528 通过Zend_Cache删除缓存
    • 23.5 Zend_Paginator分页
    • 实例529 Zend_Paginator实现数据分页显示
    • 实例530 通过修改样式做成下拉列表分页
    • 23.6 Zend_Form表单
    • 实例531 使用Zend_Form制作用户注册表单
    • 实例532 使用Zend_Form制作用户登录页面
    • 23.7 Zend_Auth身份认证
    • 实例533 使用Zend_Auth对用户身份进行验证
    • 实例534 身份持久认证
    • 23.8 Zend_Acl权限管理
    • 实例535 通过Zend_Acl控制角色和资源的权限
    • 实例536 通过Zend_Acl完成精细的访问权限控制
    • 23.9 Zend_Db数据库操作
    • 实例537 Zend_Db_Adapter数据库操作
    • 实例538 Zend_Db_Table数据库操作
    • 实例539 数据表类
    • 23.10 Zend_File文件控制
    • 实例540 使用Zend_File_Transfer_Adapter_Http
    • 实现POST方式文件上传
    • 实例541 对上传文件的合理性验证
    • 实例542 为上传增加过滤规则
    • 实例543 使用Zend Framework实现查询结果的关键字描红
    • 第24章 明日导航网(ThinkPHP)
    • 24.1 数据库设计
    • 实例544 创建数据库
    • 实例545 创建数据表
    • 24.2 MVC框架结构搭建
    • 实例546 ThinkPHP框架的MVC目录结构
    • 实例547 ThinkPHP框架的MVC结构创建过程
    • 24.3 前台设计
    • 实例548 连接数据库
    • 实例549 前台首页设计
    • 实例550 前台首页子页面设计
    • 24.4 后台管理设计
    • 实例551 创建后台管理架构
    • 实例552 后台登录
    • 实例553 后台管理主页设计
    • 实例554 高级类别管理
    • 实例555 判断访问用户的权限
    • 实例556 操作提示页面
    • 实例557 ThinkPHP框架中的分页技术
    • 第25章 明日搜索引擎(Zend Framework)
    • 25.1 数据库设计
    • 实例558 创建数据库
    • 实例559 创建数据表
    • 25.2 MVC框架结构搭建
    • 实例560 Zend Framework框架的MVC目录结构
    • 实例561 Zend Framework框架的MVC结构创建过程
    • 25.3 前台设计
    • 实例562 首页设计
    • 实例563 用户注册
    • 实例564 用户登录
    • 实例565 发表问题
    • 实例566 回复问题
    • 实例567 验证码生成
    • 实例568 类似Google搜索引擎的搜索条
    • 实例569 使用空格分隔多关键字
    • 实例570 查询结果的分页输出
    • 实例571 关键字描红
    • 实例572 制作在线编辑器
    • 实例573 自定义错误页面
    • 25.4 后台设计
    • 实例574 后台管理员登录
    • 实例575 用户管理
    • 实例576 退出登录

     

    读书笔记

    PHP调整数组顺序使奇数位于偶数前(代码/闭包扩展)

    php如何实现原址排序数组使奇数位于偶数前面(代码)

    输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

    1、遍历数组,判断元素奇数偶数,push进新数组,空间换时间

    2、插入排序的思想 空间上是原址排序

    2.1从前往后遍历,判断当前的是奇数

    2.2从当前的开始,从后往前遍历,如果是偶数就往后一位移动

    2.3当前奇数插入位置

    for i=1;i<arr.length;i++
        target=arr[i]
        if arr[i]%2==1
            j=i-1
            while j>=0&&arr[j]%2==0
                arr[j+1]=arr[j]
                j--
            arr[j+1]=target
    <?php
    $arr=array(1,2,3,4,5,6,7,8,9,10);
    function reOrderArray($arr){
            $length=count($arr);
            //从前往后遍历
            for($i=1;$i<$length;$i++){
                    //判断当前元素是奇数
                    $target=$arr[$i];
                    if($target%2==1){
                            //从后往前遍历,如果有偶数就往后移动一位
                            $j=$i-1;
                            while($j>=0 && $arr[$j]%2==0){
                                    $arr[$j+1]=$arr[$j];
                                    $j--;
                            }   
                            //把奇数插入位置
                            $arr[$j+1]=$target;
                    }   
            }   
            return $arr;
    }
     
    $arr2=reOrderArray($arr);
    var_dump($arr2);
    array(10) {
      [0]=>
      int(1)
      [1]=>
      int(3)
      [2]=>
      int(5)
      [3]=>
      int(7)
      [4]=>
      int(9)
      [5]=>
      int(2)
      [6]=>
      int(4)
      [7]=>
      int(6)
      [8]=>
      int(8)
      [9]=>
      int(10)
    }

    调整数组顺序使奇数位于偶数前(闭包扩展)

    这道题意思就是,给所有奇数放到偶数前面,我们可以设置两个指针,一个从前往后,直到他扫到偶数,一个从后往前,直到他扫到奇数,然后交换两个数的位置,然后往下扫,当begin>end的时候停止。代码实现很简单,如下:

    <?php
    //调整数组,使奇数位于偶数前面
    
    function reorder($arr){
            $length = count($arr);
            $begin = 0;
            $end = $length - 1;
            while($begin < $end){
                    //向后移动begin,直到它指到偶数
                    while(($begin < $end) && (($arr[$end] & 0x1) != 0)){
                            $begin++;
                    }
    
                    //向前移动end,指到它指到奇数
                    while(($begin < $end) && (($arr[$end] & 0x1) == 0)){
                            $end--;
                    }
    
                    if($begin < $end){
                            $temp = $arr[$begin];
                            $arr[$begin] = $arr[$end];
                            $arr[$end] = $temp;
                    }
            }
            return $arr;
    }
    
    $arr = [1,2,3,4,5,6,7,8];
    var_dump(reorder($arr));

    上面需要注意的时,判断一个数是奇数还是偶数的时候,我用的$num & 0x1 如果等于1,则为奇数,等于0,则为偶数,效率比%要高一些。

    到这里,如果单纯对于这道题,已经算是完事了。

    但是如果题目一改,将所有偶数放于奇数前,你可能又要重写一个函数了。

    这时,需求又改了,将所有能被3整除的放到前面………

    所有负数放到前面…….

    写完以上那么多函数,发现这些函数都类似啊,只有判断条件不一样。

    我们可不可以将整个函数,解耦成两部分,一个是判断数字应该在函数的前半部分还是后半部分,一个是交换数组位置。

    这时候我们就用到了闭包,代码如下

    <?php
    //调整数组,使奇数位于偶数前面
    
    function reorder($arr, $func){
            $length = count($arr);
            $begin = 0;
            $end = $length - 1;
            while($begin < $end){
                    //向后移动begin,直到它指到偶数
                    while(($begin < $end) && (!$func($arr[$begin]))){
                            $begin++;
                    }
    
                    //向前移动end,指到它指到奇数
                    while(($begin < $end) && ($func($arr[$end]))){
                            $end--;
                    }
    
                    if($begin < $end){
                            $temp = $arr[$begin];
                            $arr[$begin] = $arr[$end];
                            $arr[$end] = $temp;
                    }
            }
            return $arr;
    }
    
    $func = function($condition){
            $flag = ($condition & 0x1) == 0;
            return $flag;
    };
    
    $arr = [1,2,3,4,5,6,7,8];
    var_dump(reorder($arr, $func));

     

    《PHP、MySQL与JavaScript学习手册》学习笔记与总结

    php常用系统函数大全

    字符串函数

    strlen:获取字符串长度,字节长度

    substr_count 某字符串出现的次数

    substr:字符串截取,获取字符串(按照字节进行截取)

    mb_strlen
    mb_substr

    strchr:与substr相似,从指定位置截取一直到最后

    strrchr(获取文件后缀名):与strchr一样,只是从右边开始查找字符

    strtolower:所有的字符都小写(针对英文字母)

    strtoupper:所有的字符都大写

    strrev:字符串反转(只能反转英文:英文存储只有一个字节),按照字节进行反转

    strpos:从字符串中找对应字符出现的位置(数字下标),从最左边开始找

    strrpos:与strpos一样,只是从字符串的右边开始找

    trim:去掉函数两边的字符,默认是空格

    str_split 函数把字符串分割到数组中。

    chunk_split() 函数把字符串分割为一连串更小的部分

    str_repeat("Shanghai",5);把字符串 "Shanghai " 重复 5 次

    str_replace('\\', '/', dirname(DIR))); 替换

    ucfirst 首字母大写

    时间日期函数

    time:得到当前时间的时间戳(整型:从格林威治时间1970年1月1日0时0分0秒开始)秒数

    date:时间序列化函数,将指定的时间戳转换成规定时间日期的显示格式(随意的字符串:有专业的格式符规定),如果没有指定时间戳,系统默认使用当前时间的时间戳

    strtotime:时间日期格式的字符串转换成对应的时间戳(只要是正确的英语时间表达方式,都可以进行转换)

    microtime:微秒时间戳,根据不同的要求返回不同的结果 混合 microtime (布尔类型 ),可以返回一个浮点数的时间,也可以返回一个数组(时间戳和微秒数)

    数学相关函数

    abs:绝对值

    floor:向下取整 floor(3.2) 结果等于3

    ceil:向上取整

    round:四舍五入

    rand:取得一个指定范围内的随机整数

    mt_rand:取得一个指定范围内的随机整数(效率更高)

    min:PHP 会将非数值的 string 当成 0,但如果这个正是最小的数值则仍然会返回一个字符串。如果多个参数都求值为 0 且是最小值,min() 会返回按字母表顺序最小的字符串,如果其中没有字符串的话,则返回数值的 0;

    max:PHP 会将非数值的字符串当成 0,但如果这个正是最大的数值则仍然会返回一个字符串。如果多个参数都求值为 0 且是最大值,max() 会返回其中数值的 0,如果参数中没有数值的 0,则返回按字母表顺序最大的字符串。对于多个数组,max从左到右比较;如果同时出现数组和非数组参数总把数组作为最大值返回;

    数组相关函数

    count() // 非数组返回1

    key:获取当前数组当前指针所指向的元素的下标

    current:获取的当前指针指向元素的数值

    next:获取下一个元素的值,并且将指针下移

    prev:获取上一个元素的值,并且将指针上移

    end :将指针移到数组的最后一个元素,并返回最终指针位置的值

    reset:将指针移到数组的第一个元素,返回最终指针位置的值

    array_keys:获取一个数组的所有键名,返回一个索引数组

    array_values:获取一个数组的所有值,返回一个索引数组

    explode:爆炸,将一个字符串按照某个指定的规则(通常是特殊字符),将数组分成多个段,每一段都当做一个数组的元素,返回一个索引数组

    split 类似 explode explode('.', 'abc.txt')等于split('\.','abc.txt')

    implode:粘合,将一个数组内部的所有元素按照某个指定的规则(特殊字符),将所有的元素拼接成一个字符串

    join() 把数组元素组合为一个字符串

    array_merge:合并,指的是将两个数组中的元素进行累计。如果后面的数组与前面的数组有下标(键名:关联)相同的,那么后面的元素的值会覆盖前面的;如果是索引的相同下标,会自动的修改下标叠加到前面的数组里。

    array_reverse — 返回反转后的数组

    array_flip — 交换数组中的键和值

    数据结构模拟函数

    array_shift:从数组的前面弹出元素,得到元素的值

    array_pop:从数组的后面弹出元素,获得元素的值

    array_unshift:从数组的前面压入元素,得到当前数组元素的个数

    array_push:从数组的后面压入元素,得到当前数组元素的个数

    判断变量

    is_bool:判断是否是布尔类型

    is_float:判断浮点型

    is_integer:判断整型

    is_object:判断对象

    is_array:判断数组

    is_string:判断字符串

    is_resource:判断资源

    is_scalar:scalar是标量的,判断是基本数据类型:整型,浮点型,布尔型和字符串型

    is_null 检测变量是否为NULL 是返回TRUE 否则返回false。1.被赋值为NULL;2.变量没被赋值;3.被unset()

    is_numeric:判断数字或者纯数字组成的字符串

    gettype:获得数据类型

    settype:改变数据类型

    isset

    unset() 如果在函数中 unset() 一个全局变量,则只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值,如果在函数中 unset() 一个通过引用传递的变量,则只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值。

    empty//array(),"",0,"0",NULL,FALSE 都返回true

    文件操作函数

    opendir(路径):打开一个路径资源(将路径内部的所有数据读入到内存)

    readdir(路径资源):从文件夹资源中读取当前资源指针所指向的文件的名字,指针会向下移动一位

    closedir(资源):释放对应的文件资源

    scandir(路径):读取一个路径内部的所有文件名,返回一个数组,数组的每一个元素都是文件名。

    file_exists:判断一个文件是否存在(文件是广义:路径和文件)

    is_dir:判断一个指定路径是否存在(文件夹)

    is_file:判断一个指定路径是否是文件(文件)

    mkdir:创建一个路径,如果路径存在就会报错

    rmdir:移除文件夹

    file_get_contents:从一个指定的文件内读取数据内容。

    file_put_contents:将指定的字符串写入到对应的文件

    fopen:打开一个文件资源

    fgetc:c代表character,一次读取一个字符

    fgets:s代表string,代表可以读取多个字符,取决于指定的读取长度或者是否碰到换行(最多只能读取一行数据)

    两个函数都是对当前资源指针进行操作,读取之后都会将指针下移

    fread:获取指定长度的数据直到文件结束

    fwrite:向文件资源指针所在的位置写入数据,写东西不会将当前位置已有的东西往后移,而是会覆盖

    fseek:将指针指定到对应的位置

    fclose:使用对应的文件资源

    copy:复制

    unlink:删除文件

    rename:重命名文件

    filemtime:m代表modify,文件最后被修改的时间

    filesize:文件大小(字节)

    fileperms:文件权限(Linux下的八进制)

    排序

    rsort() 函数用于对数组单元从高到低进行排序。
    asort() 函数用于对数组单元从低到高进行排序并保持索引关系。
    arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。
    ksort() 函数用于对数组单元按照键名从低到高进行排序。
    krsort() 函数用于对数组单元按照键名从高到低进行排序。

    报错

    error_reporting(E_ALL)

    ini_set('display_errors', 1)

    常量

    define() 定义常量
    defined() 检测常量是否定义

    序列化

    serialize

    unserialize

    json_encode 对变量进行 JSON 编码

    json_decode 对JSON 格式的字符串进行编码

    编码

    base64_encode 本函数将字符串以 MIME BASE64 编码。在 BASE64 编码后的字符串只包含英文字母大小写、阿拉伯数字、加号与反斜线,共 64 个基本字符,不包含其它特殊的字符,因而才取名 BASE64。

    base64_decode 解码

    MySQL常用命令

    # @Date    : 2017-11-15 13:18:34
    # @Author  : 师兵范 (shibingfan@163.com)
     
    #常用MySQL数据库命令
    +------------+----------------+
    | COMD       |   DESCRIPTION  | 
    +------------+----------------+
    |ALTER       |修改            |
    |BACKUP      |备份            | 
    |\C          |取消输入        | 
    |CREATE      |创建            | 
    |DELETE      |删除行          | 
    |DESCRIBE    |表结构          | 
    |DROP        |删除            | 
    |EXIT(CTRL-C)|退出            | 
    |GRANT       |修改权限        | 
    |HELP(\h,\?) |帮助            | 
    |INSERT      |插入            | 
    |LOCK        |锁住            | 
    |QUIT(\q)    |退出            | 
    |RENAME      |重命名          | 
    |SHOW        |项目说明        | 
    |SOURCE      |从文件名执行命令| 
    |STATUS(\s)  |显示当前状态    | 
    |TRUNCATE    |清空表          | 
    |UNLOCK      |解锁表          | 
    |UPDATE      |更新数据        | 
    |USE         |打开数据库      | 
    +------------+----------------+
    #显示已有数据库
    mysql> SHOW databaseS; 
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | drupal7            |
    | mysql              |
    | northwind          |
    | performance_schema |
    | shibingfan         |
    | sys                |
    | testdb             |
    +--------------------+
    8 rows in set (0.06 sec)
    #创建数据库
    mysql> CREATE DATABASE publications;
    Query OK, 1 row affected (0.03 sec)
    #使用数据库
    mysql> USE publications;
    Database changed
    #数据库授权
    mysql> GRANT ALL ON publications.* TO 'shibingfan'@'localhost' IDENTIFIED BY 'shibingfan';
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    #创建数据库表
    mysql> CREATE TABLE classics(
        -> author VARCHAR(128),
        -> title VARCHAR(128),
        -> type VARCHAR(16),
        -> YEAR char(4))ENGINE  MyISAM;
    Query OK, 0 rows affected (0.08 sec)
    #查询表结构
    mysql> DESCRIBE classics;
    +--------+--------------+------+-----+---------+-------+
    | Field  | Type         | Null | Key | Default | Extra |
    +--------+--------------+------+-----+---------+-------+
    | author | varchar(128) | YES  |     | NULL    |       |
    | title  | varchar(128) | YES  |     | NULL    |       |
    | type   | varchar(16)  | YES  |     | NULL    |       |
    | YEAR   | char(4)      | YES  |     | NULL    |       |
    +--------+--------------+------+-----+---------+-------+
    4 rows in set (0.02 sec)
    #数据类型
    CHAR(n)   VARCHAR(n)
    BINARY(n) VARBINARY(n)
    TEXT(n)   TINYTEXT(n)   MEDIUMTEXT(n)  LONGTEXT(n)
    TINYBLOB(n)  BLOB(n)
    TINYINT   SMALLINT      MEDIUMINT      INT/INTEGER    BIGINT
    FLOAT     DOUBLE/REAL
    DATETIME  DATE          TIMESTAMP      TIME           YEAR
    INT UNSIGNED,  NOT NULL,  AUTO_INCREMENT,  KEY
    #添加表列id
    mysql> ALTER TABLE classics ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT KEY;
    Query OK, 0 rows affected (0.06 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    #删除表列
    mysql> ALTER TABLE classics DROP id;
    Query OK, 0 rows affected (0.08 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    #向表中添加数据
    mysql> INSERT INTO classics(author,title,type,year)VALUES('Shibingfan', 'LEARN MYSQL', 'EDUCATION', '1887');
    Query OK, 1 row affected (0.00 sec)
    #重命名表
    mysql> ALTER TABLE classics RENAME mytable ;
    Query OK, 0 rows affected (0.02 sec)
    #改变列数据类型
    mysql> ALTER TABLE mytable MODIFY year SMALLINT;
    Query OK, 5 rows affected (0.08 sec)
    #添加新列
    mysql> ALTER TABLE mytable ADD pages SMALLINT UNSIGNED;
    Query OK, 5 rows affected (0.08 sec)
    #重命名列
    mysql> ALTER TABLE mytable CHANGE type category VARCHAR(16);
    Query OK, 0 rows affected (0.31 sec)
    #删除列
    mysql> ALTER TABLE mytable DROP pages;//DROP命令不可逆
    Query OK, 5 rows affected (0.33 sec)
    #删除表
    mysql> DROP TABLE mytable;
    Query OK, 0 rows affected (0.02 sec)
    #创建索引
    mysql> ALTER TABLE mytable ADD INDEX(author(20));
    mysql> CREATE INDEX author ON mytable(author(20));//也可在创建表时添加索引
    Query OK, 5 rows affected (0.08 sec)
    #创建全文索引
    mysql> ALTER TABLE mytable ENGINE = MyISAM;		//将表转换为MyISAM
    mysql> ALTER TABLE mytable ADD FULLTEXT(author,title);
    #数据库查询
    SELECT * FROM mytable;
    SELECT author,title FROM mytable;
    SELECT COUNT(*) FROM mytable;			//计数
    SELECT DISTINCT author FROM mytable; 	//去重
    DELETE FROM mytable WHERE title = 'LEARN MYSQL';
    SELECT * FROM mytable WHERE author='Shibingfan';
    SELECT * FROM mytable WHERE author LIKE "Shi%";		//like关键字,模糊匹配
    SELECT author FROM mytable LIMIT 3;					//LIMIT关键字,限定返回的行数
    SELECT author FROM mytable LIMIT 3,1;				//LIMIT关键字,限定从表的什么位置开始返回多少行
    SELECT * FROM mytable WHERE MATCH(author,title) AGAINST('Shi'); //自然语言在FULLTEXT索引列上搜索
    SELECT * FROM mytable WHERE MATCH(author,title) AGAINST('+Shi -bing' IN BOLLEAN MODE);//布尔模式下搜索
    UPDATE mytable SET author='Shibf' WHERE author='shibingfan'; 	//更新数据
    SELECT author,title FROM mytable ORDER BY author;				//排序
    SELECT category,COUNT(author) FROM mytable GROUP BY category;	//分组
    #连接表,新建customers表
    SELECT * FROM mytable,customers WHERE mytable.isbn=customers.isbn;
    SELECT * FROM customers NATURAL JOIN mytable;		//自然连接,将相同列名的表自动合并
    SELECT * FROM customers JOIN mytable ON mytable.isbn=customers.isbn;
    SELECT author,title FROM mytable AS au,ti;			//AS重命名
    SELECT * FROM mytable,customers WHERE mytable.isbn=customers.isbn AND author='shibingfan';
     
     
    #事物
    #事物存储引擎InnoDB
    mysql> CREATE TABLE accounts(number INT, balance FLOAT, PRIMARY KEY(number))ENGINE InnoDB;
    mysql> INSERT INTO accounts(number,balance) VALUES(12345,1025.50);
    mysql> INSERT INTO accounts(number,balance) VALUES(67890,140.00);
    mysql> SELECT * FROM accounts ;
    +--------+---------+
    | number | balance |
    +--------+---------+
    |  12345 |  1025.5 |
    |  67890 |     140 |
    +--------+---------+
    #事物处理BEGIN, COMMIT, ROOLBACK
    mysql> BEGIN;
    mysql> UPDATE accounts SET balance=balance+25.11 WHERE number=12345;
    mysql> COMMIT; 		//确认提交,数据库发生更改
    mysql> ROLLBACK;	//回滚操作,数据库恢复到BEGIN之前的状态
    #使用EXPLAIN,得到查询快照,进而对查询进行优化
    mysql> EXPLAIN SELECT * FROM accounts WHERE number='12345';
    +----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
    | id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
    +----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
    |  1 | SIMPLE      | accounts | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
    +----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
    #备份和恢复
    mysql> LOCK TABLES mytable READ,accounts READ;		//锁定表UNLOCK TABLES;
    mysql> mysqldump -u user -ppassword publications;
    mysql> mysqldump -u user -ppassword publications mytable > mytable.sql;
    mysql> mysqldump -u user -ppassword publications --all-database > all_db.sql;
    mysql> mysqldump -u user -ppassword < all_db.sql;
    mysql> mysqldump -u user -ppassword -D publications < mytable.sql;

     

    PHP7协程概念以及实现方法

    php7协程知识点

    多任务 (并行和并发)

    在讲协程之前,先谈谈多进程、多线程、并行和并发。

    对于单核处理器,多进程实现多任务的原理是让操作系统给一个任务每次分配一定的 CPU 时间片,然后中断、让下一个任务执行一定的时间片接着再中断并继续执行下一个,如此反复。

    由于切换执行任务的速度非常快,给外部用户的感受就是多个任务的执行是同时进行的。

    多进程的调度是由操作系统来实现的,进程自身不能控制自己何时被调度,也就是说: 进程的调度是由外层调度器抢占式实现的

    而协程要求当前正在运行的任务自动把控制权回传给调度器,这样就可以继续运行其他任务。这与抢占式的多任务正好相反, 抢占多任务的调度器可以强制中断正在运行的任务, 不管它自己有没有意愿。如果仅依靠程序自动交出控制的话,那么一些恶意程序将会很容易占用全部 CPU 时间而不与其他任务共享。

    协程的调度是由协程自身主动让出控制权到外层调度器实现的

    回到刚才生成器实现 xrange 函数的例子,整个执行过程的交替可以用下图来表示:

    协程可以理解为纯用户态的线程,通过协作而不是抢占来进行任务切换。

    相对于进程或者线程,协程所有的操作都可以在用户态而非操作系统内核态完成,创建和切换的消耗非常低。

    简单的说协程 就是提供一种方法来中断当前任务的执行,保存当前的局部变量,下次再过来又可以恢复当前局部变量继续执行。

    我们可以把大任务拆分成多个小任务轮流执行,如果有某个小任务在等待系统 IO,就跳过它,执行下一个小任务,这样往复调度,实现了 IO 操作和 CPU 计算的并行执行,总体上就提升了任务的执行效率,这也便是协程的意义

    多线程

    在单核下,多线程必定是并发的;

    不过现在的统一进程的多线程是可以运行在多核CPU下,所以可以是并行的

    并发(Concurrency)

    是指能处理多个同时性活动的能力,并发事件之间不一定要同一时刻发生。

    并行(Parallesim)

    是指同时发生的两个并发事件,具有并发的含义,而并发则不一定并行。
    多个操作可以在重叠的时间段内进行。

    并行和并发区别

    并发指的是程序的结构,并行指的是程序运行时的状态

    并行一定是并发的,并行是并发设计的一种

    单线程永远无法达到并行状态

    协程

    协程的支持是在生成器的基础上, 增加了可以回送数据给生成器的功能(调用者发送数据给被调用的生成器函数).

    这就把生成器到调用者的单向通信转变为两者之间的双向通信.

    我们在上篇文章已经讲过了send方法, 下面让我们理解下协程

    同步代码

    在没有涉及到异步执行代码之前,我们的代码都是这样的

    function printNum($max, $caller)
    {
      for ($i=0; $i<$max; $i++ ) {
        echo "调度者:" . $caller . " 打印:" . $i . PHP_EOL;
      }
    }
     
    printNum(3, "caller1");
    printNum(3, "caller2");
     
    # output
    调度者:caller1 打印:0
    调度者:caller1 打印:1
    调度者:caller1 打印:2
    调度者:caller2 打印:0
    调度者:caller2 打印:1
    调度者:caller2 打印:2

    使用协程后改进的代码

    初稿,手动调整生成器执行

    # 本代码手动调整了进程执行代码的顺序,当然本代码实现不用协程也可以,只是利用本流程说明协程作用
    # 生成器给了我们函数中断,协程[生成器send]给了我们重新唤起生成器函数的能力
    function printNumWithGen($max)
    {
      for ($i=0; $i<$max; $i++ ) {
        $res = yield $i;
        echo $res;
      }
    }
     
    $gen1 = printNumWithGen(3);
    $gen2 = printNumWithGen(3);
     
    // 手动执行caller1 再 caller2
    $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL);
    $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL);
     
    // 手动执行caller1 再 caller2
    $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL);
    $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL);
     
    // 手动执行caller2 再 caller1
    $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL);
    $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL);
     
    # output
    调度者: caller1 打印:0
    调度者: caller2 打印:0
    调度者: caller1 打印:1
    调度者: caller2 打印:1
    调度者: caller2 打印:2
    调度者: caller1 打印:2

    总结

    上面案例应该让大家理解了协程设计的意义和如何使用协程

    那么接下去我们为我们的协程自动一个自动调度器(Co自动执行器),无需再手动来中断和恢复了

    PHP7下协程的实现方法

    前言

    相信大家都听说过『协程』这个概念吧。

    但是有些同学对这个概念似懂非懂,不知道怎么实现,怎么用,用在哪,甚至有些人认为yield就是协程!

    我始终相信,如果你无法准确地表达出一个知识点的话,我可以认为你就是不懂。

    我写这篇文章的目的,是想对鸟哥文章做更加充足的补充,毕竟有部分同学的基础还是不够好,看得也是云头雾里的。

    什么是协程

    先搞清楚,什么是协程。

    你可能已经听过『进程』和『线程』这两个概念。

    进程就是二进制可执行文件在计算机内存里的一个运行实例,就好比你的.exe文件是个类,进程就是new出来的那个实例。

    进程是计算机系统进行资源分配和调度的基本单位(调度单位这里别纠结线程进程的),每个CPU下同一时刻只能处理一个进程。

    所谓的并行,只不过是看起来并行,CPU事实上在用很快的速度切换不同的进程。

    进程的切换需要进行系统调用,CPU要保存当前进程的各个信息,同时还会使CPUCache被废掉。

    所以进程切换不到费不得已就不做。

    那么怎么实现『进程切换不到费不得已就不做』呢?

    首先进程被切换的条件是:进程执行完毕、分配给进程的CPU时间片结束,系统发生中断需要处理,或者进程等待必要的资源(进程阻塞)等。你想下,前面几种情况自然没有什么话可说,但是如果是在阻塞等待,是不是就浪费了。

    其实阻塞的话我们的程序还有其他可执行的地方可以执行,不一定要傻傻的等!

    所以就有了线程。

    线程简单理解就是一个『微进程』,专门跑一个函数(逻辑流)。

    所以我们就可以在编写程序的过程中将可以同时运行的函数用线程来体现了。

    线程有两种类型,一种是由内核来管理和调度。

    我们说,只要涉及需要内核参与管理调度的,代价都是很大的。这种线程其实也就解决了当一个进程中,某个正在执行的线程遇到阻塞,我们可以调度另外一个可运行的线程来跑,但是还是在同一个进程里,所以没有了进程切换。

    还有另外一种线程,他的调度是由程序员自己写程序来管理的,对内核来说不可见。这种线程叫做『用户空间线程』。

    协程可以理解就是一种用户空间线程。

    协程,有几个特点:

    • 协同,因为是由程序员自己写的调度策略,其通过协作而不是抢占来进行切换
    • 在用户态完成创建,切换和销毁
    • ⚠️ 从编程角度上看,协程的思想本质上就是控制流的主动让出(yield)和恢复(resume)机制
    • 迭代器经常用来实现协程

    说到这里,你应该明白协程的基本概念了吧?

    PHP实现协程

    一步一步来,从解释概念说起!

    可迭代对象

    PHP5提供了一种定义对象的方法使其可以通过单元列表来遍历,例如用foreach语句。

    你如果要实现一个可迭代对象,你就要实现Iterator接口:

    <?php
    class MyIterator implements Iterator
    {
     private $var = array();
     public function __construct($array)
     {
      if (is_array($array)) {
       $this->var = $array;
      }
     }
     public function rewind() {
      echo "rewinding\n";
      reset($this->var);
     }
     public function current() {
      $var = current($this->var);
      echo "current: $var\n";
      return $var;
     }
     public function key() {
      $var = key($this->var);
      echo "key: $var\n";
      return $var;
     }
     public function next() {
      $var = next($this->var);
      echo "next: $var\n";
      return $var;
     }
     public function valid() {
      $var = $this->current() !== false;
      echo "valid: {$var}\n";
      return $var;
     }
    }
    $values = array(1,2,3);
    $it = new MyIterator($values);
    foreach ($it as $a => $b) {
     print "$a: $b\n";
    }

    生成器

    可以说之前为了拥有一个能够被foreach遍历的对象,你不得不去实现一堆的方法,yield关键字就是为了简化这个过程。

    生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现Iterator接口的方式,性能开销和复杂性大大降低。

    <?php
    function xrange($start, $end, $step = 1) {
     for ($i = $start; $i <= $end; $i += $step) {
      yield $i;
     }
    }
    foreach (xrange(1, 1000000) as $num) {
     echo $num, "\n";
    }

    记住,一个函数中如果用了yield,他就是一个生成器,直接调用他是没有用的,不能等同于一个函数那样去执行!

    所以,yield就是yield,下次谁再说yield是协程,我肯定把你xxxx。

    PHP协程

    前面介绍协程的时候说了,协程需要程序员自己去编写调度机制,下面我们来看这个机制怎么写。

    0)生成器正确使用

    既然生成器不能像函数一样直接调用,那么怎么才能调用呢?

    方法如下:

    • foreach他
    • send($value)
    • current / next...

    1)Task实现

    Task就是一个任务的抽象,刚刚我们说了协程就是用户空间协程,线程可以理解就是跑一个函数。

    所以Task的构造函数中就是接收一个闭包函数,我们命名为coroutine。

    /**
     * Task任务类
     */
    class Task
    {
     protected $taskId;
     protected $coroutine;
     protected $beforeFirstYield = true;
     protected $sendValue;
    
     /**
      * Task constructor.
      * @param $taskId
      * @param Generator $coroutine
      */
     public function __construct($taskId, Generator $coroutine)
     {
      $this->taskId = $taskId;
      $this->coroutine = $coroutine;
     }
     /**
      * 获取当前的Task的ID
      * 
      * @return mixed
      */
     public function getTaskId()
     {
      return $this->taskId;
     }
     /**
      * 判断Task执行完毕了没有
      * 
      * @return bool
      */
     public function isFinished()
     {
      return !$this->coroutine->valid();
     }
     /**
      * 设置下次要传给协程的值,比如 $id = (yield $xxxx),这个值就给了$id了
      * 
      * @param $value
      */
     public function setSendValue($value)
     {
      $this->sendValue = $value;
     }
     /**
      * 运行任务
      * 
      * @return mixed
      */
     public function run()
     {
      // 这里要注意,生成器的开始会reset,所以第一个值要用current获取
      if ($this->beforeFirstYield) {
       $this->beforeFirstYield = false;
       return $this->coroutine->current();
      } else {
       // 我们说过了,用send去调用一个生成器
       $retval = $this->coroutine->send($this->sendValue);
       $this->sendValue = null;
       return $retval;
      }
     }
    }

    2)Scheduler实现

    接下来就是Scheduler这个重点核心部分,他扮演着调度员的角色。

    /**
     * Class Scheduler
     */
    Class Scheduler
    {
     /**
      * @var SplQueue
      */
     protected $taskQueue;
     /**
      * @var int
      */
     protected $tid = 0;
    
     /**
      * Scheduler constructor.
      */
     public function __construct()
     {
      /* 原理就是维护了一个队列,
       * 前面说过,从编程角度上看,协程的思想本质上就是控制流的主动让出(yield)和恢复(resume)机制
       * */
      $this->taskQueue = new SplQueue();
     }
     /**
      * 增加一个任务
      *
      * @param Generator $task
      * @return int
      */
     public function addTask(Generator $task)
     {
      $tid = $this->tid;
      $task = new Task($tid, $task);
      $this->taskQueue->enqueue($task);
      $this->tid++;
      return $tid;
     }
     /**
      * 把任务进入队列
      *
      * @param Task $task
      */
     public function schedule(Task $task)
     {
      $this->taskQueue->enqueue($task);
     }
     /**
      * 运行调度器
      */
     public function run()
     {
      while (!$this->taskQueue->isEmpty()) {
       // 任务出队
       $task = $this->taskQueue->dequeue();
       $res = $task->run(); // 运行任务直到 yield
    
       if (!$task->isFinished()) {
        $this->schedule($task); // 任务如果还没完全执行完毕,入队等下次执行
       }
      }
     }
    }

    这样我们基本就实现了一个协程调度器。

    你可以使用下面的代码来测试:

    <?php
    function task1() {
     for ($i = 1; $i <= 10; ++$i) {
      echo "This is task 1 iteration $i.\n";
      yield; // 主动让出CPU的执行权
     }
    }
    function task2() {
     for ($i = 1; $i <= 5; ++$i) {
      echo "This is task 2 iteration $i.\n";
      yield; // 主动让出CPU的执行权
     }
    }
    $scheduler = new Scheduler; // 实例化一个调度器
    $scheduler->newTask(task1()); // 添加不同的闭包函数作为任务
    $scheduler->newTask(task2());
    $scheduler->run();

    关键说下在哪里能用得到PHP协程。

    function task1() {
      /* 这里有一个远程任务,需要耗时10s,可能是一个远程机器抓取分析远程网址的任务,我们只要提交最后去远程机器拿结果就行了 */
      remote_task_commit();
      // 这时候请求发出后,我们不要在这里等,主动让出CPU的执行权给task2运行,他不依赖这个结果
      yield;
      yield (remote_task_receive());
      ...
    } 
    function task2() {
     for ($i = 1; $i <= 5; ++$i) {
      echo "This is task 2 iteration $i.\n";
      yield; // 主动让出CPU的执行权
     }
    }

    这样就提高了程序的执行效率。

    关于『系统调用』的实现,鸟哥已经讲得很明白,我这里不再说明。

    3)协程堆栈

    鸟哥文中还有一个协程堆栈的例子。

    我们上面说过了,如果在函数中使用了yield,就不能当做函数使用。

    所以你在一个协程函数中嵌套另外一个协程函数:

    <?php
    function echoTimes($msg, $max) {
     for ($i = 1; $i <= $max; ++$i) {
      echo "$msg iteration $i\n";
      yield;
     }
    }
    function task() {
     echoTimes('foo', 10); // print foo ten times
     echo "---\n";
     echoTimes('bar', 5); // print bar five times
     yield; // force it to be a coroutine
    }
    $scheduler = new Scheduler;
    $scheduler->newTask(task());
    $scheduler->run();

    这里的echoTimes是执行不了的!所以就需要协程堆栈。

    不过没关系,我们改一改我们刚刚的代码。

    把Task中的初始化方法改下,因为我们在运行一个Task的时候,我们要分析出他包含了哪些子协程,然后将子协程用一个堆栈保存。(C语言学的好的同学自然能理解这里,不理解的同学我建议去了解下进程的内存模型是怎么处理函数调用)

     /**
      * Task constructor.
      * @param $taskId
      * @param Generator $coroutine
      */
     public function __construct($taskId, Generator $coroutine)
     {
      $this->taskId = $taskId;
      // $this->coroutine = $coroutine;
      // 换成这个,实际Task->run的就是stackedCoroutine这个函数,不是$coroutine保存的闭包函数了
      $this->coroutine = stackedCoroutine($coroutine); 
     }

    当Task->run()的时候,一个循环来分析:

    /**
     * @param Generator $gen
     */
    function stackedCoroutine(Generator $gen)
    {
     $stack = new SplStack;
     // 不断遍历这个传进来的生成器
     for (; ;) {
      // $gen可以理解为指向当前运行的协程闭包函数(生成器)
      $value = $gen->current(); // 获取中断点,也就是yield出来的值
      if ($value instanceof Generator) {
       // 如果是也是一个生成器,这就是子协程了,把当前运行的协程入栈保存
       $stack->push($gen);
       $gen = $value; // 把子协程函数给gen,继续执行,注意接下来就是执行子协程的流程了
       continue;
      }
      // 我们对子协程返回的结果做了封装,下面讲
      $isReturnValue = $value instanceof CoroutineReturnValue; // 子协程返回`$value`需要主协程帮忙处理 
      if (!$gen->valid() || $isReturnValue) {
       if ($stack->isEmpty()) {
        return;
       }
       // 如果是gen已经执行完毕,或者遇到子协程需要返回值给主协程去处理
       $gen = $stack->pop(); //出栈,得到之前入栈保存的主协程
       $gen->send($isReturnValue ? $value->getValue() : NULL); // 调用主协程处理子协程的输出值
       continue;
      }
      $gen->send(yield $gen->key() => $value); // 继续执行子协程
     }
    }

    然后我们增加echoTime的结束标示:

    class CoroutineReturnValue {
     protected $value;
     
     public function __construct($value) {
      $this->value = $value;
     }
     // 获取能把子协程的输出值给主协程,作为主协程的send参数
     public function getValue() {
      return $this->value;
     }
    }
    function retval($value) {
     return new CoroutineReturnValue($value);
    }

    然后修改echoTimes:

    function echoTimes($msg, $max) {
     for ($i = 1; $i <= $max; ++$i) {
      echo "$msg iteration $i\n";
      yield;
     }
     yield retval(""); // 增加这个作为结束标示
    }

    Task变为:

    function task1()
    {
     yield echoTimes('bar', 5);
    }

    这样就实现了一个协程堆栈,现在你可以举一反三了。

    4)PHP7中yield from关键字

    PHP7中增加了yield from,所以我们不需要自己实现携程堆栈,真实太好了。

    把Task的构造函数改回去:

     public function __construct($taskId, Generator $coroutine)
     {
      $this->taskId = $taskId;
      $this->coroutine = $coroutine;
      // $this->coroutine = stackedCoroutine($coroutine); //不需要自己实现了,改回之前的
     }

    echoTimes函数:

    function echoTimes($msg, $max) {
     for ($i = 1; $i <= $max; ++$i) {
      echo "$msg iteration $i\n";
      yield;
     }
    }

    task1生成器:

    function task1()
    {
     yield from echoTimes('bar', 5);
    }

    这样,轻松调用子协程。

    总结

    这下应该明白怎么实现PHP协程了吧?

    实例分析PHP7的异常

    PHP 7 异常用于向下兼容及增强旧的assert()函数。它能在生产环境中实现零成本的断言,并且提供抛出自定义异常及错误的能力。

    老版本的API出于兼容目的将继续被维护,assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的 string或一个待测试的boolean。

    assert() 配置

    配置项默认值可选值
    zend.assertions1 1 - 生成和执行代码 (开发模式) 0 - 生成代码,但在执行时跳过它 -1 - 不生成代码 (生产环境)
    assert.exception0 1 - 断言失败时抛出,可以抛出异常对象,如果没有提供异常,则抛出 AssertionError 对象实例。 0 - 使用或生成 Throwable, 仅仅是基于对象生成的警告而不是抛出对象(与 PHP 5 兼容)

    参数

    assertion

    断言。在 PHP 5 中,是一个用于执行的字符串或者用于测试的布尔值。在 PHP 7 中,可以是一个返回任何值的表达式, 它将被执行结果用于指明断言是否成功。

    description

    如果 assertion 失败了,选项 description 将会包括在失败信息里。

    exception

    在 PHP 7 中,第二个参数可以是一个 Throwable 对象,而不是一个字符串,如果断言失败且启用了 assert.exception 该对象将被抛出。

    实例

    将 zend.assertions 设置为 0:

    <?php 
    ini_set('zend.assertions', 0); 
    
    assert(true == false); 
    echo 'Hi!'; 
    ?>

    以上程序执行输出结果为:

    Hi!

    将 zend.assertions 设置为 1,assert.exception 设置为 1:

    <?php 
    ini_set('zend.assertions', 1); 
    ini_set('assert.exception', 1); 
    
    assert(true == false); 
    echo 'Hi!'; 
    ?>

    以上程序执行输出结果为:

    Fatal error: Uncaught AssertionError: assert(true == false) in -:2
    Stack trace:
    #0 -(2): assert(false, 'assert(true == ...')
    #1 {main}
      thrown in - on line 2

     

    上一篇:PHP核心技术与最佳实践  下一篇:深入PHP:面向对象、模式与实践

    展开 +

    收起 -

     
    PHP开发 相关内容
    PHP+MySQL动态网站开发从入门到精通

    《PHP+MySQL动态网站开发从入门到精通》本书循序渐进地介绍了PHP 7 MySQL 5.7开发动态网站的主要知识和技能,提供案例、课件、命令速查手册,让你看得懂、学得会、做得出,教你快速成为网站应用开发高手。

    查看详情
    PHP从入门到精通

    《php从入门到精通(第4版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用PHP进行网络开发应该掌握的各方面技术。《php从入门到精通(第4版)》共分4篇25章,

    查看详情
    PHP与MySQL高性能应用开发

    PHP与MySQL高性能应用开发书中不仅讲解了OOP、设计模式,也讲解了如何进行性能优化和调试。甚至,还对于语言之外的代码重构进行了讲解,本书面向的对象是有一定PHP基础,但是又想深入学习的PHP开发者,欢迎免费下载

    查看详情
    PHP 7 编程实战

    PHP7挟很多的、强劲的新作用和小工具强劲而成,应用这种作用和小工具能够 提升编码,编写出比老PHP版本号程序流程速度相当快的程序流程。这书主要详细介绍了PHP7有关的高级PHP编程技术。

    查看详情
    PHP、MySQL与JavaScript学习手册

    本书有借助面向对象的编程基础,深入学习PHP。研究MySQL,从数据库结构到复杂查询。掌握JavaScript语言,以及带有jQuery的增强功能。调用Ajax进行后台浏览器/服务器通信等,欢迎免费下载

    查看详情
    Learning PHP设计模式

    本书是PHP设计模式的经典教程,让读者掌握更精巧的编程风格。本书利用大量浅显易懂的例子告诉你如何应用多种面向对象模式,并展示了这些模式在一些成熟的实际项目中的具体应用,欢迎免费下载

    查看详情
    ThinkPHP实战

    《ThinkPHP实战》实战性很强,没有冗长的概念讲解,都是实际项目中使用的实用技术,比如验证码、文件上传、图像处理、调试、安全、缓存等。留言板、博客、论坛、微信公众平台开发4个实战项目案例,使读者尽快切入ThinkPHP企业级项目开发。

    查看详情
    《PHP开发实例大全:提高卷》学习笔记
    网友NO.486642

    比较完整的微信开发php代码

    本文实例为大家分享了微信开发php代码,供大家参考,具体内容如下 ?php //封装成一个微信接口类 class WeixinApi { private $appid; private $appsecret; //构造方法 初始化赋值 public function __construct($appid="",$appsecret="") { $this-appid = $appid; $this-appsecret = $appsecret; } //验证服务器地址有效性 public function valid() { if($this-checkSignature()) { $echostr = $_GET['echostr'];//随机的字符串 return $echostr; } else { return "Error"; } } //检查签名 private function checkSignature() { //一、接收微信服务器GET方式提交过来的4个参数数据 $signature = $_GET['signature'];//微信加密签名 $timestamp = $_GET['timestamp'];//时间戳 $nonce = $_GET['nonce'];//随机数 //二、加密/校验过程 // 1. 将token、timestamp、nonce三个参数进行字典序排序; // bool sort ( array //将上面三个参数放到一个数组里面 sort($tmpArr,SORT_STRING); // 2. 将三个参数字符串拼接成一个字符串进行sha1加密; $tmpStr = implode($tmpArr); //将数组转化成字符串 $signatureStr = sha1($tmpStr); // 3. 开发者获得加密后的字符串与signature对比。 if($signatureStr == $signature) { return true; } else { return false; } } //响应消息 public function responseMsg() { //接收微信服务器发送POST请求到开发者服务器,携带的XML数据包 $postData = $GLOBALS['HTTP_RAW_POST_DATA']; //处理xml数据包 $xmlObj = simplexml_load_string($postData,"Simp……

    网友NO.130637

    php微信公众号里快递查询开发详解

    本文实例为大家分享了php微信公众号开发之快递查询的具体代码,供大家参考,具体内容如下 快递查询 数组用法 foreach 查询接口是: 爱快递:https://www.aikuaidi.cn/api/ 核心代码 如下: $postObj = simplexml_load_string($postStr, SimpleXMLElement, LIBXML_NOCDATA); $fromUsername = $postObj-FromUserName; $toUsername = $postObj-ToUserName; $type = $postObj-MsgType; $customrevent = $postObj-Event; $latitude = $postObj-Location_X; $longitude = $postObj-Location_Y; $keyword = trim($postObj-Content); $time = time(); $textTpl = xml ToUserName![CDATA[%s]]/ToUserName FromUserName![CDATA[%s]]/FromUserName CreateTime%s/CreateTime MsgType![CDATA[%s]]/MsgType Content![CDATA[%s]]/Content FuncFlag0/FuncFlag /xml; switch ($type) { case text; $status=array(0=查询出错,1=暂无记录,2=在途中,3=派送中,4=已签收,5=拒收,6=疑难件,7=退回);//构建快递状态数组 $kuaidiurl=http://www.aikuaidi.cn/rest/?key=ff4735a30a7a4e5a8637146fd0e7cec9order={$keyword}id=shentongshow=xml;//快递地址 $kuaidistr=file_get_contents($kuaidiurl);//读入文件 $kuaidiobj=simplexml_load_string($kuaidistr);//xml解析 $kuaidistatus = $kuaidiobj-Status;//获取快递状态 $kuaistr=strval($kuaidistatus);//对象转换为字符串 $contentStr0 =$status[$kuaistr];//根据数组返回 foreach ($kuaidiobj-Data-Order as $a) { foreach ($a-Time as $b) { foreach ($a-Content as $c) { $m.={$b}{$c};} } } //遍历获取快递时间和事件 $contentStr=你的快……

    网友NO.477334

    ThinkPHP框架实现的微信支付接口开发完整示例

    本文实例讲述了ThinkPHP框架实现的微信支付接口开发。分享给大家供大家参考,具体如下: 微信支付接口开发很简单我们只需要在官方申请权限然后参考官方的文章即可实现支付开发了,下面来看一个简单的例子,具体如下。 最近有个微商城做了微信支付的接口,现在整理一下发上来。 首先是需要有已开通微信支付接口的公众号,这个相信大家都知道,开通之后微信会发一封邮件到你的邮箱,邮件的内容就是开发需要用到的一些接口信息了(包含账号密码之类的东西)。 开发步骤 一、进入公众号平台,先设置几个参数,包括绑定域名、设置回调地址等等。 1、在设置 - 公众号设置 - 功能设置 - 设置JS接口安全域名 2、在微信支付 - 开发配置 - 配置你的js支付接口,回调地址等等,正式目录和测试目录都可以写上,测试目录需要把个人微信号先添加到白名单才能使用(提醒:用TP框架的小伙伴们在填写支付授权目录时可以这样填写:域名/index.php/控制器/,经测试是可以通过的,微信一样能检测到,之前看到网上有人说这样不行,可能是现在升级了吧,呵呵,还有一个就是域名一定要是已经备过案的才行,如果是在本地进行测试的小伙伴们可以使用花生壳,我不是在打广告,个人觉得还是挺好用的) 3、在开发者中心把网页授……

    网友NO.315654

    Docker搭建自己的PHP开发环境

    1. 前言 1.1 为什么要用Docker ? 是否有这样的场景,你搞了一个项目,在本地开发时需要搭建环境,放到线上时也需要搭建环境,到公司想暗戳戳玩一下要搭建环境,不搭还不行,因为你的环境依赖还挺多。这个时候如果有了Docker,只需要在机器上装个Docker,放上写好的Dockerfile,一行命令就自动完成这个事,方便又高效,岂不是很爽? 1.2 准备 接下来,本文介绍如何搭建一个PHP的开发环境,将用 zPhal-dockerfiles 做为例子,这是我为我的博客系统准备的一套Dockerfile。 现在不管是Windows、Mac还是Linux,Docker都可以很好支持,包括Windows系统,在Win 10系统下Docker for Windows 其实还是挺不错的,就是比较吃内存。 通过Docker命令行,我们可以做很多事情,拉取镜像,运行容器,容器内执行命令等,但是现在,我们要用更加简单粗暴的方式,编写好Dockerfiles文件,然后通过docker-compose管理好这些文件,简化操作流程。 什么是Dockerfile? Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于拉取的基础镜像并最终创建一个新的镜像,通过Dockerfile我们可以创建一个你需要的镜像,里面是包含了你要安装的软件,相当于是提前定制好要安装的拓展,执行的命令等,然后一键执行,极大地简化操作流程。 按照本文来搭建环境,你需要: 首先了……

    Copyright 2018-2020 xz577.com 码农之家

    本站所有电子书资源不再提供下载地址,只分享来路

    免责声明:网站所有作品均由会员网上搜集共同更新,仅供读者预览及学习交流使用,下载后请24小时内删除

    版权投诉 / 书籍推广 / 赞助:QQ:520161757