一.入门指引
1.php是什么?
PHP是什么?
Hypertext Preprocessor,超文本预处理器
Personal Home Page,个人主页
是一种在服务器端执行的脚本语言,可嵌入到 HTML中,尤其适合 web 开发。
?
-
php可以做什么?
网站,web程序 B/S架构
?
?
命令行脚本
桌面应用程序
?
?
二.安装Apache
制作一台服务器,来提高网页服务,只要安装了一个能提供网页服务的软件的电脑,就可以称之为网页服务器。
常见的网页服务器软件
- Apache
- IIS
- Nginx
?
安装Apache
1. 在D盘根目录下新建一个文件,命名为amp,并分别创建apache、php和mysql文件夹
2. 填写基本信息
?
- 选择自定义安装,
?
?
?
?
?
- 选择安装路径
?
- 安装,完成
?
6测试安装是否成功
在浏览器中,输入http://localhost,看到如下界面,就表示安装成功
分析:it work是哪里来的?
?
在htdocs 下,有一个html页面,如下:
?
Apache默认的文档目录,apache/htdocs
默认的索引页:index.html
?
Apache的安装易出问题的地方:
关于端口的占用问题,http的端口是80,迅雷用的也是80端口。
什么是静态网站,什么是动态网站?
?
是否和数据库打交道,动态网站的内容是随时变化的,而静态则一成不变(除非更改源代码)。
?
对于动态网站而言,我们需要提供一个数据源,通常情况下,是由数据库来完成的。比如mysql
?
对于apache而言,他只能管理文件和文件夹,并不能完成和数据库的交互,也不能完成逻辑代码的编写,所以,我们需要一门语言来完成这个工作,这就是PHP了。
?
对于静态网站来说,只有html,css和javascript,而动态网站,则包括一门语言和数据库(PHP+MySQL)
?
?
三.安装PHP
Php并没有独立的安装程序,它是作为apache的一个模块来安装的。
安装步骤
- 在amp目录下新建一个文件夹,命名为php,然后将php安装包拷贝到该目录下,并解压。
- 然后配置apache
- 找到httpd.conf文件
?
- 具体配置
?
要讲php作为apache的一个模块来运行,将php配置为apache的一个模块,使用loadmodule指令完成。
LoadModule 模块名 模块文件
?
?
凡是php文件,要指定将其php模块来处理。配置这个的指令有三种:
第一种:使用addtype指令,
?
第二种:使用addhandler指令
?
这种,有一个小问题,就是只有文件名中含有.php,都会被当做php文件来解析。所以一般不推荐
?
第三种:使用FilesMatch指令
?
PHP在运行的时候,需要载入php的配置文件,由于php是作为apache的一个模块来运行的,所以我们需要告知apache,这个配置在哪里。
?
找到php.ini相关文件
?
复制其中一个,然后更名为php.ini
使用PHPIniDir配置,设置PHP。Ini路径
?
?
有了上述三个配置,基本上就可以完成apache和php的整合。
?
?
注意,配置文件,很容易出错,一般来说,一个指令尽量要顶格写。
?
有时候,还需要对php进行一些初始化设置。需要在php.ini文件中进行相应的配置。
?
常用的配置:
Extension,php扩展库目录
?
?
在默认情况下,所有的扩展库都是关闭的,所以我们还需要手动开启相应的一些扩展库,比如gd库、myslq扩展库。
?
市区设置
?
一定要注意,在php.ini配置过程中,要顶格写。
每一次配置都需要重启apache才能生效,php.ini也是一样。
?
php与apache之间的联系
Php作为apache的一个模块来运行的,php和apache是通过CGI来关联的。
建议大家使用php5.3版本。
?
四.安装MySQL
安装步骤
- 在amp下新建一个目录,命名为mysql
- 安装
- 选择自定义安装
- 选择安装目录和数据存放目录
?
- 启动配置向导
- 选择详细配置
- 选择开发者机器
- 多功能
- 端口和模式设置
- 选择字符集
- 设置path
- 设置密码
?
出现了错误
?
?
- 安装完成
?
测试安装
?
Php连接mysql。
测试
在phpinfo中查看是否有mysql,
?
可以编写一段代码来测试,
?
可以安装一个phpmyadmin来测试
将phpmyadmin解压到在htdocs下,然后更名为phpmyadmin,然后访问即可。
输入用户名和密码,进入主界面
?
?
Mysql安装最容易出问题的当然,是卸载之后的安装,原因在于卸载并不彻底,主要是这数据存放目录data。默认在C:\C:\ProgramData\Mysql\Mysql server\data
?
?
五.虚拟主机配置
通常情况下,一个web服务代理一个网站,但是有时候我们需要用一台服务器代理多个网站。这个就是基于域名的虚拟主机技术。
?
我们可以直接在httpd.conf当中进行配置,也可以使用extra中的httpd-vhosts.conf配置,建议使用第二种方式。
首先要开启vhost.conf配置,
?
打开vhost.conf进行配置
?
为了使用基于域名的虚拟主机技术,我们需要指定服务器的ip和端口来接收服务。
这个通过NameVirtualHost 指令完成。
NameVirtualHost *:80
如果端口不是80 必须要改端口的,这句很关键
?
其中*表示所有的ip地址,如果是一个具体的ip,你可以写上这个ip,但建议使用*,80指的是端口。
接下来,要单独的配置具体的域名,通过 VirtualHost 指令段,其参数必须和NameVirtualHost
而且在指令段中必须包含ServerName 和 DocumentRoot
?
?
配置hosts文件,指定域名和DNS的对应关系。
?
?
?
?
通过浏览器访问某个域名的时候,需要进行域名的解析,首先找本地的hosts文件,如果能解析,就使用本地的配置,如果不能解析,则去外网进行解析。
?
?
现在去访问localhost,会怎么样?
会访问到在vhost文件中配置的第一个虚拟主机。
?
默认的虚拟主机,如果访问一个url,没有配置对应的虚拟主机,则会访问到vhost文件中配置的第一个虚拟主机。
?
?
再来配置一个
?
那如果要访问原来的localhost。
?
?
在hosts文件配置域名ip对应关系
?
?
? 配置细节
- 配置项一般不区分大小写,但参数通常是大小写敏感的
- 配置项要顶格写,否则无效
- #表示注释
- / 和 \ 的使用,路径的结尾不用添加斜线,建议使用/
- "" 的使用,地址要使用引号包含
- Apache 的每一次配置,包括后面的php.ini的配置,都需要重启apache才能生效
- 如果配置错误,则Apache不能正常启动
?
思考一个问题:
一个主配置httpd.conf,一个是辅助配置文件vhost.conf
如果关闭辅助文件,然后再来访问localhost,会怎么样?
在主配置文件中,有如下配置:
?
六.访问权限配置
在G盘中配置一个虚拟主机shop.cc,然后在浏览器中进行访问,
?
说明没有权限。
Apache有一个严格的权限控制。
?
通过directory指令来进行权限的配置。
默认的一个权限配置
?
?
第一种解决方案:在主配置文件中配置directory段,如下
?
第二种解决方案,在辅助文件中,对应的virtualhost 指令段中进行配置(推荐)
?
?
注意,这个配置要求更加严格,
?
将shop网站下的index.html更名为index1.html,出现如下状况:
?
默认的索引页,
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
?
在默认情况下,只索引index.html,如果要默认能够访问index.php,可以在此处添加
DirectoryIndex index.html index.php
?
?
索引列表
如果没有默认的索引页,它会将该文件夹下面的所有文件以列表的形式展示出来,但是需要有权限才行。
?
?
在实际的网站部署时,索引列表是应该 关闭的 。
FollowSymLinks 是指的符号链接,linux系统才有效。
?
关于Deny 和 Allow 的说明
[总则]:
影响最终判断结果的只有两点:
- order语句中allow、deny的先后顺序;
- allow、deny语句中各自包含的范围。
?
修改完配置后要保存好并重启Apache服务,配置才能生效;
开头字母不分大小写;
allow、deny语句不分先后顺序,谁先谁后不影响最终判断结果,但都会被判断到;
order语句中,"allow,deny"之间"有且只有"一个逗号(英文格式的),而且先后顺序很重要;
Apache有一条缺省规则,"order allow,deny"本身就默认了拒绝所有的意思,因为deny在allow的后面;同理,"order deny,allow"本身默认的是允许所有;
"order allow,deny"代表先判断allow语句再判断deny语句,反之亦然。
?
如果主文件和辅助文件都配置了权限,会怎么办?
以辅助文件为主
注意options这个指令,不会叠加,所以有时候我们会看到在indexes 有一个 + 或者 -的出现。
?
?
七.分布式配置文件
?
.htaccess
分布式配置文件,名字是固定的
?
?
配置分布式文件步骤:
- 开启分布式配置,默认情况下,这个是关闭的
将 AllowOverride None 改为 AllowOverride All 就开启了分布式配置
?
- 创建.htaccess
使用editplus编辑器或其他高级编辑器来创建
?
?
- 配置相应的权限
凡是写在directory中的权限配置都可以写在这个文件当中。
deny from All
?
分布式配置文件修改之后,不需要重启,立即生效。
?
和directory配置一样,所配置的权限在该目录及其子目录生效。
?
?
思考:使用.htaccess好不好?
?
优点:方便,给内容提供者一个自由配置权限的机会。
?
缺点:性能所损失(不小),只要开启分布式配置,那么它会在每个文件夹下搜索.htaccess。
?
一般不推荐使用分布式配置文件。
?
?
? 注意细节
- .htaccess 文件,比较特殊,可以使用 editplus 或者 ST2 等编辑器来创建。
- .htaccess 属于目录级别的控制,对应于 Directory 指令段中的配置。
- .htaccess 默认并未启用,可在主配置文件中使用allowoverride 指令加以配置。
- 配置修改.htaccess 文件,不需要重启,每次都会读取,性能有损失。
?
?
?
?
?
?
作业:配置一个虚拟主机,名字 test.ip.com,其中ip就是大家自己的IP,如test.192.168.5.32.com
?
?
?
?
?
八.Php语言基础
?
Php语言的执行周期
?
- apache来调用php模块
- 初始化php模块(读取php.ini配置文件,并加装相应的扩展库)
- 处理php代码
- 释放php的相应资源
- Php模块将处理结果返回到apache
?
?
Opcode是zend 引擎能够识别并执行的代码。
?
?
弄清一个概念?
PHP是什么类型的语言? 编译型 or 解释型
?
任何一门语言,C、PHP、java最终都要转换成机器能够识别的代码才行。这个过程通常称之为编译(解释、翻译)。
?
编译之后,得到一个编译后的代码,对于编译后的代码,在执行的时候,通常有两种选择,一是重复的执行编译后的代码,一次编译,多次运行,这种类型的就是编译型。
二是每一次执行都需要编译一次,像这种类型的就是解释型语言。
?
PHP属于解释型。
?
为什么需要标记?
<?php ?>
?
由于php是可以嵌入html代码的服务器端的脚本语言,php可以和html混在一起写,如果没有一个标记以区分哪个是PHP代码,那么php模块如何来处理php代码呢?
?
标记有四种:
- <?php ?> 标准的写法,推荐使用
- <script language=‘php‘> </script>
- <? ?> [需要开启short_open_tag] (在php.ini中开启)
- <% %> [需要开启asp_tags]
大家需要注意的 <? ?>,但是在5.3之后,默认是关闭的。
?
Php语句结束符
开启错误显示
display_errors = On
?
每一行代码必须有一个分号作为语句结束符。
Php结束符 ?> 默认包含一个语句结束符
如果php代码段是整个文档内最后的一个代码段,可以省略结束标记 ?>
?
如果整个文件都是php代码,建议不写 ?>
?
注释:
单行注释:# //
多行注释: /* */
?
? 注意细节
- 尽量多写注释
- 注释应尽量规范化 [推荐使用phpdocumentor规范]
- php注释只能注释php的代码,不能注释标签的内容
- 放在html代码注释内的php代码也会被执行
?
?
?
?
?
一.变量
1.变量概念
所谓变量,是指在程序中其值可以变化的量。
?
程序是用来管理和处理数据的。在程序运行过程当中,我们需要保存这些数据,变量和常量就是用于保存程序运行时的数据的。
?
变量通常由两部分组成,变量名 和 值
?
在php中,定义一个变量,使用$符号,在定义的时候不用理会其类型。
?
增,就是赋值,比如$a = "PHP"
改, 重新赋值即可,$a = "Mysql"
查, 通过引用的方式 如 $a
删, 使用unset
?
Unset 到底干了什么?
去掉了引用,然后销毁变量。
?
变量的命名规范
- 变量名通常是由字母、数字和下划线组成,不以数字开头。
- 见名知意
- 对于一个有多个单词组成的变量名,单词之间如何分割,firstName,first_name。(入乡随俗)
? 注意细节
- $不是变量名的一部分,这是语法,表示后边的标识符是一个变量(特殊的this)
- 当使用一个没有定义的变量时,会报一个notice错误,可以使用isset来检查
- 变量名是大小写敏感的,建议使用下划线方式
?
?
2.变量之间的赋值
在php中,变量赋值默认是采用值传递的方式。
?
?
还有一种传值的方式,就是引用传递。
?
? 注意细节
unset一个变量时,删除了该变量,以及标识符到变量之间的引用
只有有名字的变量才可以引用赋值。($bar = &(24 * 7); // 非法;)
?
3.可变变量
变量名(变量标识符),它还可以是一个变量,这就是可变变量。
?
简单的例子
在php中,不仅有可变变量,还有可变函数。
?
4.预定义变量
php中存在很多不需要用户脚本来定义就可以直接使用的变量,称之为预定义变量。
- $_POST
- $_GET
- $_REQUEST
- $_SERVER
- $_FIELS
- $_SESSION
- $_COOKIE
- $_ENV
- $GLOBALS
?
关于get和post,如果在get和post同时存在一个变量,应该取哪一个值。
?
取决于reques的顺序。
?
起作用是后面POST。
?
$_REQUST = $_POST + $_GET
?
如果能够明确是post还是get提交,就直接使用post或者get,当不明确的时候,那就可以使用$_REQUEST。
?
$_SERVER,和HTTP协议以及服务器相关的一些信息。
?
:服务器的ip地址
:浏览器请求端的IP地址
:当前请求的完整的URL路径
:文件名,相对的路径
?
? 注意细节
- 使用request时,如果post和get都有一个相同名称的变量时,则只保留post,取决于php的配置 request_order = ‘GP‘;
- $GLOBALS 引用全局作用域中可用的全部变量
?
作用域
什么是作用域?
指的是变量的生效范围。
- 全局变量
- 局部变量
- 超级全局
?
全局变量的作用域,也就是生效范围,在当前脚本,在脚本运行结束的时候失效。
?
?
二.常量
1.常量的基本用法
和变量相对应,在程序运行过程中,其值不能变化的量,这就是常量。
定义常量,需要使用define函数。
?
常量一般都使用大写,我们可以通过define函数的第三个参数来决定是否区分大小写,默认情况是大小写敏感的,设置为true,则不区分大小写,但不建议这么做。
?
常量不能重新复制,
在编程的时候,有时候不知道常量是否已经定义,或者说在常量没有定义的情况下,我就要定义它。该怎么做?
?
使用defined函数来判断常量是否已经定义。
?
常量的命名,规则和变量一致,但是使用大写。
?
变量和常量的区别
- 变量有$符号,常量没有。
- 常量只能使用define语句来定义,不能直接使用赋值语句。
- 变量是有作用域的,但是常量是没有作用域概念的。
- 常量的值一经定义,不可改变
- 常量的值只能是标量(整型,浮点,字符串,布尔)
?
在php5.3以上,还可以使用constant函数来获取常量的值。
2.预定义常量
PHP自身也提供了大量的预定义常量,可以通过get_defined_constants函数获取。
比如:
?
:换行符,很重要
不同操作系统其换行符是不同的,
Windows:\r\n *nix:\n MAC:\r
PHP_EOL,会根据不同的操作系统,使用不同的值。
?
整型的最大值,整型占用的字节数
?
目录分隔符,windows下面可以使用\ 和/,而在*nix下面则只使用/。
?
环境变量中路径与路径之间的分隔符。
?
C:\Program Files\Intel\WiFi\bin\ ; C:\Program Files\Common Files\Intel\WirelessCommon
?
在手册中的位置
3.魔术常量
形似常量,实非常量。
?
典型的应用(项目代码)
下面的写法也是可以的,但要注意__DIR__必须在PHP5.3以上版本才支持。
?
? 注意
- 它们的值随着它们在代码中的位置改变
- 这些特殊的常量不区分大小写,但尽量大写,保持一致
?
魔术常量的名称 前后都有__,所以大家在定义常量的时候,就不要使用这种形式。
?
三.数据类型
什么是数据类型?
简单来说,具有某种类型的数据,不同类型的数据在结构上、操作上都有不同的限制和约定。
在PHP中,有八种数据类型,4 + 2 + 2
4: 4种标量类型(简单),整型、浮点型、布尔、字符串
2:两种复合类型,数组和对象
2:两种特殊类型,资源和NULL。
?
?
?
PHP在定义变量的时候,是不需要声明类型的。但是它不代表没有类型的。
变量的类型是如何确定的?在程序运行的上下文来确定的。
?
如何来查看某个变量的数据类型? 使用var_dump函数。
?
?
1.整型
在php当中,整型的范围,占用 个字节,最大值是多少?
?
在PHP中,不支持符号。没有无符号的(unsigned)。
?
整型,除了可以使用十进制的表示方式之外,还可以使用八进制,16进制来表示。
八进制:以0开头,如012--->2*80 + 1 * 81 = 10
十六进制:以0x开头,0x12--->2*160 + 1 * 161 = 18
不同的位,有不同的权。
?
要将10进制转成其他进制,如2进制,8进制,16进制? 要使用长除法
55
?
在php中,提供了一系列的函数用于进制之间的转换。
? decbin:10进制 -> 2进制
? dechex:10进制 -> 16进制
? decoct:10进制 -> 8进制
? bindec:2进制 -> 10进制
? hexdec:16进制 -> 10进制
? octdec:8进制 -> 10进制
?
Dec :10进制 bin:2进制
Oct :8进制 hex:16进制
? 注意细节
- 对于整型,一旦数值过大,不会溢出,而是发生类型转换,会转成浮点型。
- php不支持无符号整型。
?
?
Php中的整型,无法定义让其只有正数部分。
2.浮点型
浮点型,在php中,float,double 实际上是相同的。
?
在PHP中浮点数具有14位十进制数字的精度,最大值 和平台相关,通常是 1.8e308。
?
注意,浮点数的比较是不靠谱的。
在编写程序的时候,不要试图通过比较两个浮点数是否相等来获得业务逻辑。
其它的定义浮点数的方式,科学计数法的方式 e或者E
3.布尔类型
这是最简单的数据类型,它只有两个值,TRUE和FALSE,而且不区分大小写。
我们经常说0表示假,非0表示真。在程序运行的时候,会转换成布尔类型。0和1本身是表示整型的。
?
?
通常情况下,布尔类型应用在程序的流程控制当中,尤其是if语句中。
4.字符串类型
一个字符串,它是由多个字符组成的,通常情况下,我们有四种方式来定义字符串。
- 双引号
- 单引号
- Heredoc (定界符)
- Newnoc (定界符)
?
在双引号中,可以解析变量,而在单引号中,是不能解析变量的。
?
在单引号中,可以包含双引号,在双引号中,也可以包含单引号。但是不能自身。
变量能不能解析,不是取决于变量被哪一个包含,而是取决于定义字符串是单引号还是双引号,如果是双引号,则变量解析,如果是单引号,则不解析。
?
在字符串中,如果有{$ 连在一起的时候,就表示{}当中的这个作为一个变量进行解析。
?
?
[需求]:使用php输出一个a标签,并给a标签定义一个点击事件,alert一句话。
?
需要使用转义字符
?
转义字符
在双引号中,支持所有的转义字符。
在单引号中,只支持‘ 和
?
使用PHP输出一段html代码
?
Heredoc的结束符必须顶格写,且改行除了结束符和;,也不能有其他的内容。
5.数组
数组是一组数据的集合,是一个复合类型的。数组可以保存多个值。
数组中的每一个元素都是由Key/value组成的键值对。
数组的基本操作
增加 定义
定义一个数组有两种方式,使用array结构或者使用 []语法
在定义的时候,可以指定下标,也可以不指定下标。
?
指定下标
下标的数据类型可以是哪一些?
通常情况下使用的是整型和字符串,当然也可以使用浮点和布尔类型。只能是标量类型。
如果是浮点数,则会取整(只取整数部分)。如果是布尔类型,true->1 false->0,不要使用浮点和布尔。
?
如果下标重复,实际上就是修改该元素,那么其结果就是修改之后的值。
在一个数组中,可以同时存在整型下标和字符串下标。
以数字作为下标,我们一般称其为 索引数组。
以字符串作为下标的,我们一般称其为关联数组。关联数组能够表示业务逻辑。
?
不指定下标
在定义数组的时候,如果省略下标,如果还没有元素的话的,就从0开始,否则元素的下标就是在当前的最大索引上加1。
?
查看
可以使用print_r 和 var_dump,可以结合pre与格式标签,不要使用echo来输出数组,它只能输出Array。
?
修改
重新赋值即可。可以使用array语言结构全部修改,或者使用[]来修改某一个元素。
?
删除
删除数组有两种情况,一是删除其中的某个(某些),而是删除整个的数组。都可以使用unset。
?
? 注意细节
- 元素的下标只能是字符串和整型,可以使用浮点数,但会被取整,如果使用字符串形式的数字,则仍会被当做整数。如果使用布尔型,则true->1 ,false-> 0
- 可以不指定下标,如果不指定下标,则系统会自动分配一个数字下标,其值是当前最大的下标 + 1。
- 如果指定的键名已经有了值,则该值会被覆盖。
- 应始终在用字符串表示的数组索引上加上引号。$foo[‘bar‘] √ $foo[bar] ×。
- 字符串的 [] 特殊用法
?
在字符串中,也可以使用数组的方式来访问该字符串中的字符。可以将字符串比作数组,而字符则是该数组中的元素。此时只针对单字节字符有效,如果是多字节,则会出现乱码。
6.对象
和数组类似,是一个复合类型的数据,数组只能保存多个变量,而对象不仅可以保存多个变量,而且还可以保存方法。有时候,我们称对象是有生命力的数组。
7.资源
在使用PHP编程的时候,有时候需要操作一些不属于PHP本身的一些资源,比如数据库,图形处理,文件处理。
当我们使用php扩展库的时候,就会得到一个资源类型的数据。
?
8.NULL
NULL表示一个变量没有值,该类型只有一个值,就是NULL,而且不区分大小写。
什么样的数据会是NULL。
?
在下列情况下一个变量被认为是 NULL:
- 被赋值为 NULL
- 尚未被赋值
- 被 unset()
?
最常见的一个应用就是将对象的值赋值为NULL,以销毁该对象。
?
9.伪类型
有时候,我们需要在程序或手册中描述数据的类型,这就是伪类型。
Number 数值型,如max函数
Mixed 混合类型(不确定),如var_dump函数
Callback 回调函数,如array_map
Void 空,如echo和pi
?
?
作业:
进制转换,十进制101转成二进制,八进制。
$a = 5, $b = 10,不用第三个变量,交换两个数的值。
利用循环及转义字符知识
输出 ASCII码中的可见字符。提示:32-126之间
?
?
?
?
?
?
?
?
?
作业说明
进制转换,十进制101转成二进制,八进制。
两种都要会,一是手算,理解原理。
二是利用系统函数,
二进制:bin
八进制:oct
十进制:dec
十六进制:hex
其它进制转成十进制,参数是字符串。
?
?
$a = 5, $b = 10,不用第三个变量,交换两个数的值。
利用加减法(正解)
?
下面的方法也可以
?
?
利用循环及转义字符知识
输出 ASCII码中的可见字符。提示:32-126之间
?
一.类型转换
?
运算数在参加运算的时候,需要将类型转为相同,然后才进行计算。在上面的例子中,第一个运算中,会先将$int转成浮点,然后和$f1相加,第二个运算中,会先将$str转成int类型,然后和$int相加。
?
在这个过程中,出现了类型转换。在上面的例子中,转换是系统自己进行的。
?
弱类型和强类型。
?
在定义一个变量的时候,不需要指定变量的类型,它的类型由程序的上下文来决定的,比如$a = 10,那就意味着$a是一个整型,$a = ‘hello‘,就意味着$a是一个字符串。
像这种确定变量类型的方式就是弱类型。
与之对应的就是强类型,比如C、java、C#等。
?
变量在参与运算的时候,类型发生了变化,但变量本身的类型并没有改变。
?
?
注意两点:
- 在参与运算的多个操作数据之间,运算之前都需要将数据类型转成一致才可以。
- 这并没有改变这些操作数本身的类型;改变的仅是这些操作数如何被求值以及表达式本身的类型。
?
通常有两种方式来完成类型转换:
- 强制转换
- 自动转换
?
强制转换,我们在需要转换的变量之前,使用类型关键字,用括号括起来。
Int 或者 interger
Float
Boolean
String
Array
Object
在PHP中,实现强制转换,在要转换的变量之前加上用括号括起来的目标类型即可。
- (int), (integer) - 转换为 整型(integer)
- (bool), (boolean) - 转换为 布尔型(boolean)
- (float), (double), (real) - 转换为 浮点型(float)
- (string) - 转换为 字符串(string)
- (array) - 转换为 数组(array)
- (object) - 转换为 对象(object)
- (unset) - 转换为 NULL
?
将其他类型转为资源类型是没有意义的。
强制转换在程序中,应用并不多,大部分情况下,使用自动类型转换就可以完成业务逻辑。
?
转换规则
?
转换成字符串
- 一个 整数 或 浮点数 被转变为数字的字面样式的字符串
- 一个boolean TRUE 值被转换成 字符串"1"。 Boolean FALSE 被转换成"" ????
- 数组转换成 字符串 "Array"
- 资源总会被转变成"Resource id #1"这种结构的 字符串
- NULL 总是被转变成空的字符串。
?
?
?
转换成整型
- 从布尔值转换,FALSE 将产生出 0(零),TRUE 将产生出 1(壹)。
- 从浮点数转换,当从浮点数转换成整数时,将向下取整。
- 从字符串转换,如果字符串 没有包含 ‘.‘,‘e‘或‘E‘ 并且数字值符合整数类型的限定 ,可被认定是一个 integer, 否则被认定为一个float。字符串的开始部分给定了它的值,如果 字符串 以合法的数字开始,这个数字可直接使用。 否则,值就是 0 。
?
转换成布尔型
当转换为 boolean 时,以下值被认为是 FALSE:
- 布尔值 FALSE 自身
- 整型值 0 (零)
- 浮点型值 0.0 (零)
- 空字符串, 以及 字符串 "0" (注意"00"、"0.0"被认为是TRUE)
- 空数组
- 特殊类型 NULL (包括尚未设定的变量)
?
所有其它值都被认为是 TRUE(包括对象和资源)。
1 和其它非零值(不论正负)一样,被认为是 TRUE!
? 注意细节
- HTML 表单并不传递整数、浮点数或者布尔值,它们只传递字符串。
- FALSE 是一个布尔值而 "false" 是一个字符串。
数据类型相关函数
- Var_dump:打印变量的详细信息,包括类型和值
- Gettype:获得类型
- Settype:设置类型
- Is系列:其中is_array会经常用到
- Isset:检查一个变量是否存在(设置)
- Empty:检查一个变量是否为空
?
对于isset而言,只要声明过(有值),不管它的值是什么,那么就返回true
对于empty而言,相当于 boolean(变量) ,然后再来取反。
简单例子
注意,在使用empty时候,要结合具体的业务逻辑类分析。
?
二.运算符
能够实现某种运算功能的符号。
根据不同的功能,可以分为以下几大类:
- 算术运算符
- 赋值运算符
- 字符串运算符
- 比较运算符
- 递增/递减运算符
- 逻辑运算符
- 位运算符
- 错误控制运算符
- 三目运算符
?
不同的运算符所对应的的运算数是不同的,单目、双目、三目。
一个运算符在进行运算的时候,需要确保运算数是一致的。
1.算术运算符
除法运算的结果,可能是浮点数,也可能是整数。
在取模运算中,如果有小数,则会去除小数部分。
在取模运算中,结果的正负取决于第一个数。
面试题:
执行程序段<?php echo 8%(-3) ?>将输出
?
2.赋值运算符
就是 =
$a = ‘php‘
?
[思考]:$a = ($b = 4) + 5; 这行代码如何理解? $a = 9
赋值运算表达式的值也就是所赋的值。也就是说,"$a = 3"的值是 3。
表达式也是有值的。
有时候我们还将 = 和其它的运算组合到一起,形成组合赋值。
$a = $a + 5 => $a += 5;
?
3.字符串运算符
只有一个,就是 点 . ,没有加号,
注意的是,点 和 赋值运算符一起 形成 组成赋值。
.=
4.比较运算符
比较运算符,比较两个运算数的关系,返回的结果是一个布尔值。
不等有两种写法,!= 和<>
?
?
? 注意细节
如果比较一个整数和字符串,则字符串会被转换为整数。如果比较两个数字字符串,则作为整数比较。
=== 和 == 的区别。比如 0 == false 返回真,而0 === false 返回假。
?
5.递增递减运算符
++ 和 --
根据其位置的不同,又分为前++,前--,后++,后--
?
前置和后置的区别?
不管是前置还是后置,变量的结果是一致的。
不同的运算的顺序,通过表达式来分析,前置,++$b,是先进行运算,然后再得到值,
而后置$b++,则是先得到值,然后进行运算。
?
?
? 注意细节
递增/递减运算符不影响布尔值。递减 NULL 值也没有效果,但是递增 NULL 的结果是 1
?
?
6.逻辑运算符
?
与:两者都为true的情况才为true and
或:两者都为false的才为false or
?
非:非真即假,非假即真,直接取反。 !
?
异或:xor,如果两者相异,结果为真,两者相同,结果为假。
?
之所以出现 && 和and 两种运算符,是由于它们的优先级不同。
?
短路运算:
在进行逻辑运算的时候,如果通过第一个参数已经能够确定整个表达式的值,那么就不会进行后面的运算。
?
对于 与 运算,如果第一个为假,则后面的不会进行计算。
对于 或 运算,如果第一个为真,则后面的不会进行计算
?
真实的代码:
?
7.位运算符
按位进行运算,
位,bit,是指二进制表示中的每一个数值。 010101
字节 Byte,是由位构成的,通常是8 bit 00001010
1KB = 1024 Byte
1MB = 1024 KB
1GB = 1024 MB
1TB = 1024GB
已知$a = 9,$b = -4,分别求: $a & $b, $a | $b, ~$b,$a ^ $b,$a >>2, $b<<2的值。
位运算都是以二进制的形式来出现的。
同时要注意,二进制的表示形式有 原码、反码、补码。
?
原码:
将十进制转成的二进制。用最高位表示符号位,0表示正数,1表示负数。
?
反码:
对于正数,反码和原码相同
对于负数,符号位不变,其它位取反。
?
补码:
对于正数,补码和原码相同
对于负数,在反码的基础上 + 1。
?
计算机在底层进行运算的时候,是以补码的形式进行的。Why?
?
$a & $b $a | $b的过程:
?
- 右移:低位溢出,符号位不变,高位用符号位补全 (相当于除以2n 然后取整)
- 左移:高位溢出,符号位不变,低位补0 (相当于乘以2n)
?
$a >> 2 和 $b << 2的运算过程:
不管是左移还是右移,它只会改变该数的大小,不改变符号,所以在移位操作的时候,符号位始终是不变的。
?
在实际编程的时候,经常会用一个位表示一种状态(或一个值)。
?
8.错误控制运算符
?
我们不期望看到错误,可以使用错误控制运算符进行屏蔽。
?
不是在每个会出现错误的地方使用这个运算,一般而言,对于我们无法控制的错误,比如去请求其它的资源的时候,可以使用。
?
? 注意细节
@ 运算符只对表达式有效。不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等。
?
9.三目运算符
从名字我们就可以得知,这个运算符有三个运算数。? :
表达式1 ? 表达式2 : 表达式3
等价于一个简单的if……else语句
If (表达式1){
表达式2
} else {
表达式3
}
使用三目运算符可以简化程序。
?
10.其它特殊运算符
主要有以下几个:
=> 数组运算符
表示键和值的对应关系
Array(‘os‘ => ‘Linux‘
[ ] 数组运算符
用于获取数组元素
-> 对象运算符
对象操作属性,以及方法的运算符
?
instanceof 对象运算符
判断某个对象是否是类的实例。
:: 域作用符,用在面向对象当中的。
?
11.结合性和优先级
先看一个问题:
?
多个运算数在参与运算的时候,要注意它们的顺序和优先级。
?
在程序当中,并不是所有的运算符都是由左向右的,有一些是从右向左,比如赋值=。
一般来说,单目运算符比双目运算符的优先级高。
?
= 的优先级比较低,比它还低的有 and or xor ,
And 和 && 的区别
? 注意细节
- 运算符优先级指定了两个表达式绑定得有多"紧密"。
- 同一行中的运算符具有相同优先级,此时它们的结合方向决定求值顺序。
- 必要时可以用括号来强制改变优先级。可以增强代码的可读性。
- && || 与 and or的区别
- 尽管 = 比其它大多数的运算符的优先级低,PHP 仍旧允许类似如下的表达式:if (!$a = foo()),在此例中 foo() 的返回值被赋给了 $a。
?
如果在编写代码的时候,对于运算比较复杂(运算符较多),可以使用()来改变优先级。
?
?
表达式
任何有值的东西,都是表达式。
赋值语句,函数的调用,
表达式本身也有值。
?
$b = ($a = 5)
$a=5 是一个表达式,这个表达式本身有值,值就是$a的值。
?
三.流程控制
任何PHP脚本都是有一系列的语句组成,可以是一个赋值语句,一个函数的调用,也可以是一个空语句。
?
通过语言结构,来控制程序的执行的顺序,这就是流程控制。
?
通常有三大流程控制:
- 顺序
- 分支(选择)
- 循环
?
一般而言,在编写程序之前,都会绘制一个图形的流程图。尤其是对于那些业务逻辑比较复杂的程序。
?
绘制流程图常用的图例:
?
开始/结束
?
进程(流程)
判断
程序的走向
输入和输出
?
1. 顺序结构
按照程序书写代码的顺序来执行。
?
?
2.分支结构
根据不同的条件,来执行不同的流程。在php中,有两个系列,一个是if系列,一个是switch系列。
?
If系列
在if系列的分支结构中,又分为三种:
- 单分支
- 双分支
- 多分支
单分支
是简单的一种的分支结构,if语句
?
双分支
向左走还是向右走的。使用if……else来实现
多分支
要进行多次的条件判断,使用if……elseif……elseif……else
?
elseif 还可以分开写 else if, 分开写实际上是if……else的嵌套的写法。
两种写法的结果并没有什么不同的。
If语句的替代写法。
将 { 用 : 来替代,将 } 用endif 来替代。
?
注意elseif 和 else……if 的替代语法的区别
?
作业
echo count("abc"); 输出什么?(新浪?)
自己编写程序,测试下面的结果
已知$a = 9,$b = -4,分别求: $a & $b, $a | $b, ~$b,$a ^ $b,$a >>2, $b<<2的值。
?
面试题:使用一句代码实现求三个数中的最大值,提示使用三目运算符。
?
输入一个分数,来判断它的等级,100 A+, 90-100 A, 80-90 B 70-80 C 60-70D, 使用if的替代语法的形式来完成。
?
复习
?
整型
范围4个字节,
正负,
进制概念
可以采用 10进制,8 进制, 16进制的形式,去表示一个整型数!
?
浮点
双精度,8个字节
不能比较
可以使用科学计数法表示
?
字符串
单引号,双引号,定界符
heredoc,可以解析内部变量
<<<HTML
字符串内容
HTML;
nowdoc,不可以解析内部变量
<<<‘HTML‘
字符串内容
HTML;
?
不要直接写字符串内容,不对!
将字符串变量也使用双引号包裹,不好!
?
?
?
字符串支持下标的操作!
看成一个字符的集合!
只针对单字节字符有效,多字节字符无效!
单字节字符,指的是一个字符占用一个字节的存储空间,例如英文,数字,标点符号等
多字节字符,指的是一个字符占用多个字节的存储空间,例如汉字,韩文等。
字符集的概念,指的是一个可见字符,在计算机中是如何存储的,因为jsj只能存储的是二进制数据,而我们看到的是各种各样的字符,之间的映射关系,就是字符集编码做的工作!
例如,我们看到的小写a,它在计算器中保存的是0 1100001为什么会这样,因为ascii码规定的!assii就是一个最基本的字符集!所有的字符集,几乎都对ascii有兼容!
?
?
字符串函数
?
布尔
true false TRUE FALSE
?
数组
数组的下标,整型和字符串类型
空字符串下标,可以存在
默认的下标是,整型,从0开始递增
?
?
?
对象
类,class,对象的设计图
对象,object,类实例化的成品
实例化,new,利用类,得到对象的过程
属性,property,对象内部的变量,对象保存数据的成员
方法,method,对象内部的函数,对象操作数据的成员
->,对象访问成员(属性,方法)的方法
?
?
NULL
资源
php外部数据的引用!
?
?
类型转换
计算机中的数据类型,指的是,一种特殊的数据结构,与对应的结构的特殊操作,组成一数据类型
?
因此,不同类型对应的操作是不同的,因此计算时需要转换成一致的类型!
?
期望的类型,与得到的类型不一致,要转换!
自动转换
手动(强制)转换
(目标类型) 待转换的数据
?
操作符,运算符
?
表达式,一个经过计算可以得到数据的语句。
一个典型的表达式,由数据与操作符组成!
?
算术
比较(关系),都会返回布尔数据,php判断我们所写的关系表达式是否成立,成立返回true,不成立返回false!
逻辑运算符,计算多个关系之间的结果!参与逻辑运算的都是布尔值,返回也是布尔值!
异或,相同为假,不同为真!
短路运算。
false&&
true ||
?
andpk&&
?
递增/递减<,并不是严格的+1,-1,而是在原有数据上增加或者减少!
++/--
其他类型也可以参与递增递减,是在原数据上增加减少
例如,字符串,可以递增,不能递减
?
前置++ 后置++
赋值
=, +=, -=, .=
?
三目
运算数1? 运算数2:运算数3;
三目运算符,返回一个数据!
?
错误控制
@,屏蔽错误信息!
?
位运算
bit,比特。
一个整型做位运算,要计算 32 次,因为 32 位!
?
~ 位非
&位与
| 位或
^ 位异或
?
补码计算机
原码,使用绝对值表示大小
反码,原码取反。
补码,反码+1。
?
转换原则:
- 整数的原码,反码,补码三码一致!
- 负数在转换时,符号位不变,值的部分转换!
?
?
?
为什么要使用补码?
cpu,只有加法器,没有减法器!
?
5-3 = 2
5 + (-3) = 2//如何计算得到?
分别采用原码与补码进行演算!
采用补码,不用考虑符号的问题,直接结算就可以得到正确的结果!
?
正负零的问题
补码不会出现正负零的问题,而补码将 1 0000000 这个编码强制分配给最小的负数,
导致负数的最小值的绝对值,要比正数最大值的绝对值> 1。
?
-2147483648 ~~ 2147483647
?
>>
<<
?
?
位运算可以干什么?
管理一组开关状态!
?
假设管理5盏灯的状态!
?
判断某盏灯是否是开启或者是关闭!
判断第三(四)盏灯的状态
判断某位是否是1,或者是0.
?
位与上相应位的状态数!
其中,状态数,表示某位的状态的整数,特点是,相应位为1,其他位为0.
例如,第三位的状态数久违:(二进制)00100
第四位:(二进制) 01000
原值 |
运算 |
? | ? | ? |
1 |
0 |
0 |
? | ? |
0 |
0 |
0 |
? | ? |
1 |
1 |
1 |
? | ? |
0 |
1 |
0 |
? | ? |
? | ? | ? | ? | ? |
?
$status & 00100
11001 & 00100 = 00100
?
如何开灯?
打开第二盏灯,保证其他灯原样!
将相应位,强制置1
位或上,当前位的状态数即可!
原值 |
或运算 |
? | ? | ? |
1 |
0 |
1 |
? | ? |
0 |
0 |
0 |
? | ? |
1 |
1 |
1 |
? | ? |
0 |
1 |
1 |
? | ? |
? | ? | ? | ? | ? |
? | ? | ? | ? | ? |
或0,原来不变
或1,一定为1
?
?
如何关灯?
将相应位,强制置0,保持其他位不变!
与上,相应的状态数取反即可
?
原值 |
位与运算 |
? | ? | ? |
1 |
0 |
0 |
? | ? |
0 |
0 |
0 |
? | ? |
1 |
1 |
1 |
? | ? |
0 |
1 |
0 |
? | ? |
与0,一定为0
与1,原值不变!
?
切换状态?
原来为1,设置为0.原来为0设置成1
异或上,相应位的状态数即可!
?
原值 |
位异或运算 |
? | ? | ? |
1 |
0 |
1 |
? | ? |
0 |
0 |
0 |
? | ? |
1 |
1 |
0 |
? | ? |
0 |
1 |
1 |
? | ? |
异或0,原值不变
异或1,原值取反
?
预习
switch 状态分支
for,while do-while 循环
break,continue;
include/require/文件载入,include_path,绝对地址,相对地址
return,die,sleep
函数。
作业
bit.php
?
2, 配置检查域名
要求大家配置域名相同:
test.100.com
?
IP 36,test.36.com/bit.php
?
?
?
else if elseif区别?
if
else
if
endIf;
endIf;
作业回顾
?
得到数据先做判断是否存在:
isset可以判断一个变量是否存在,一个元素是否存在,一个对象的属性是否存在!isset判断一个不存在的变量,不会触发notice级别的错误!
?
使用位运算完成操作:
不要用加法代替,位或。一来速度慢,而来是出现进位的可能(如果是在原有值上做运算)。
?
switch分支
?
多分支,与elseif类似,但是,区别是,一旦某个条件(状态值匹配),则会执行当前case的进程体,余下的进程体,也会被执行,而不会再做条件case判断,直到运行到,switch结束,或者碰到break;
?
执行流程
?
switch状态分支
if-elseif与 switch 不同的地方:
都是多分支!
?
if-elseif称之条件分支!判断的依据是某个条件!
switch 称之为状态分支!判断的依据是某个固定值!意味着,判断依据一定是等于某种状态!
?
name,case中可以出现条件表达式么?逻辑含义是什么?
可以出现,与elseif所表示的逻辑关系,不完全一致!
?
原因,switch是状态分支,判断的依据是状态。switch在判断哪个case满足条件之前,将case后的表达式,计算出状态值才可以!(先计算出结果,得到一个值,再与判断的数做比较)
?
?
如何选择?
看判断的依据,有限的几个状态值,选择使用 switch!
?
?
进程的终止
break可以终止进程!
其实 continue 也可以!
原因是。php再对 switch处理时,将其当作循环结构看待!当作只有一次循环体执行的循环看待!
?
?
switch也支持替代语法:
?
?
?
循环流程结构
将一段代码,重复的执行多次!在某种特定的条件下,重复执行!
?
for循环结构
问题:
如果循环体执行N次,那么三个表达式分别执行多少次?
初始化1, 1 次。
条件判断2, N+1次。
条件变化3,N次。
?
执行流程
?
典型的,用于得到一串连续的值。例如,典型的一个都是整型下标,由0开始递增的数组,就可以利用for循环,得到其所有的元素内容!(数组简单遍历)
最好长度可以计算出来:
利用函数 count()计算出来数组长度!
?
?
语法问题
表达式多语句
每个表达式都可以由多条语句组成,使用逗号分隔
多条语句都会执行:
如果条件表达式由多个语句,则只有后边的才能生效:
适用于,在循环时,条件发生变化的情况!因为所有的语句都会执行!
?
?
表达式可以为空
没有语句
表达式可以没有,但是分割表达式的分号,必须存在
其中,省略条件表达式,表示条件为真!死循环,无限循环!
只有循环体内,存在跳出循环的 break语句时,有其含义!
?
可以省略其中部分!
?
循环变量可以被操作
循环结束后,该循环变量的值还是存在
可以获得其值,并且是个不符合条件的值!
?
在循环体内,也可以更改循环变量的值
由于可以影响循环的判断,因此可以出现由于循环体内的修改,导致死循环的情况
同样支持替代语法
while循环
语法:
?
注意,其实在整体代码内,也是会出现初始化和条件变化的,但是不会直接出现在whlie内:
?
因此,典型的,比较适用于,循环条件相对明确,但是循环次数不是容易确定的循环!
while,就相当于省略了第一和第三个表达式的for循环!
?
?
?
?
do-while循环结构
语法
会先执行一次循环体,再做条件判断!如果条件满足,则再次执行循环体!
与 while相比,会先执行一次循环体,可以保证循环至少被执行一次!
?
典型的,循环条件需要在循环体内得到,会使用该结构!
?
例如:
成绩单,输出所有的学生的成绩,直到第一个语文成绩大于其平均分的学生为止!
?
语文????数学
89????????91
90????????92
78????????68
89????????89
?
结果:
语文????数学????平均
89????????91????????90
90????????92????????91
78????????68????????73
?
?
关于替代语法,while正常,而do-while没有!
?
循环的终止
典型的,条件不满足,则循环体终止执行!
提前终止循环!
break
终止,当执行到break时,整体的循环循环语句直接结束
continue
继续,当前循环体结束执行,而继续执行下次循环体!
终止嵌套循环
循环体,是由多条语句组成!也可以是循环语句!
例如 99 乘法表!
1*1 =1
2*1 = 2 2* 2=4
3*1=3
双层循环即可!
问题:
当我碰到第一个大于30的数据后,后边的结果全部去掉!
当内层循环内,判断满足条件后,要求终止外层循环,应该为break(continue)增加一个层数,作为参数,表示其跳出的层级数!默认是一级,表示跳出当前循环!
break N; N表示循环的层数!
?
switch内终止循环
switch,终止其执行,需break!
因此,如果在循环内,通过swtich分支,来终止循环的话,switch本身也算一层循环!至少要 break 2;
?
?
?
goto
跳转到某个位置!
需要使用标签来配合;
标签名:
?
goto标签;
跳转到某个标签位置执行!
?
例如,有时再对数据做判断时,如果有错误,则直接报错即可!
?
可以使得,原本,每条都需要执行的语句,可以不被执行!
?
注意的问题
- 函数内与函数外,不能互相跳转。而且,两个函数之间也不能互相跳转!
函数外只能调到函数外,而函数内,只能跳转到当前函数内!(只能在相同作用域内跳转)
?
- 可以调到分支语句体内
?
- 不能向循环内,或者switch内跳转:
- 循环体内,可以跳转到循环体外:
5,标签区分大小写!
?
?
?
?
foreach
?
文件载入
require include require_onceinclude_once
以上4个语法,功能一致,效果略有不同!
?
将目标文件内的代码载入当前内,进行执行!目的是为了重用某段代码!
?
require ‘文件名‘;
引入时,不在乎目标文件的类型,只在乎目标文件内的代码!
文件只是一个源代码的载体!
载入,并不是直接去执行被载入的文件,而是将被载入的文件内的代码,加载过来,然后再去执行!
?
?
文件地址
用于描述,一个文件在磁盘上的位置,文件载入,在磁盘上查找文件!
16.php:
e:/php1016/apache/htdocs/test/16.php(磁盘上的文件位置,在当前的文件系统上查找,文件路径)
http://test.100.com/16.php(网络上的资源地址,URL,统一资源定位符)
?
require后所使用的是磁盘上的文件位置!
?
分成,相对路径与绝对路径
?
相对路径
相对于当前位置的某个文件的位置。
典型的相对地址的写法如下:
./表示当前下 ./file.php
../ 表示当前上级目录 ../file.php
path/file 直接以目录名或者文件名开头 test/file.php当前目录下的test/file.php
?
格外注意,当前位置的确定,不是由代码写在哪个文件中确定的,而是有当前代码在哪里执行确定!浏览器请求谁(哪个脚本),当前地址就是哪里!
?
因此建议,项目中(目录结构复杂),最好使用绝对路径!
?
绝对路径
文件在磁盘上的真实位置!
在windows上,决定路径就是带盘符的路径!
缺点,比较长,典型的,将某部分,定义成常量!
?
?
./file.php????file.php的区别
./file.php只会在当前目录下查找!
file.php先在当前目录下查找,如果没有,会在代码所在文件目录下再查找!
?
如果可以确定文件就在当前目录下,应该使用 ./file.php增加效率!
?
file.php除了可以在所在文件目录下查找,还有一个功能。大家可以设置其查找目录!
因此,按照下面的方式查找:
?
include_path
是一个php的配置,用于配置用户查找文件的位置!默认位置为:
?
如果可能设置该配置项的值,就可以做到:
将所有被载入的文件,集中放在某几个目录内,载入时直接写文件名即可,省掉的冗长的路径的部分!
?
设置include_path
利用函数:set_include_path();
在设置时,后设置的会将前面设置的覆盖掉!
因此,典型的设置应该将已有的值,拿到,再重新设置上!
取得当前的include_path的值:
利用函数:get_include_path()可以获得当前的include_path的值!
目录之间采用分号连接.
注意上面的路径分隔符,使用的分号!
windows下:分号;
linux下:冒号:
PHP使用预定义常量:
PATH_SEPARATOR来保存当前操作系统的路径分割符!
?
注意:
include_path只针对file.php这类的路径有效!
?
预习
requirepk require
return , sleep, die
函数(定义,调用,函数名,函数参数(形参,实参,值传递,引用传递,默认值,参数数量),函数体返回值(值返回,引用返回),作用域(局部,全局,超全局),匿名函数,递归调用)
?
作业
1,画一个while的流程图 do-while的流程图
while.php
?
2,星星塔
tip:
控制好行,列(星星和空格)
如何利用行号,控制空格的和星星的数量总行数为5行!
行号 |
空格数 |
星星数 |
? | ? |
1 |
4 |
1 |
? | ? |
2 |
3 |
3 |
? | ? |
3 |
2 |
5 |
? | ? |
4 |
1 |
7 |
? | ? |
5 |
0 |
9 |
? | ? |
总结:
空格数=?总行数-行号
星星数=? 2*行号– 1
3,求最大公约数。辗转相除法
one,先计算出来!
two,学习辗转相除法!
1????2????3????4????5????4????3????2????1
-4????-3????-2????-1????0????1????2????3????4(数轴)
4????3????2????1????0????1????2????3????4(绝对值) absh函数获得数的绝对值
?
?
最大公约数
从小的数开始,到1,碰到第一个将两个数都整除的数,就是最大公约数!
?
辗转相除法
?
拿一个数对另一个数,取模(取余数),判断余数(模数)是否为零。
为零:当前的除数就是最大公约数。
不为零:拿刚刚的除数成为被除数,拿刚刚的余数作为除数,再取余。
?
再对余数(模数)是否为零做判断:判断的结果和操作都一致!
?
直到运算到余数为零,则当前的除数,就为最大公约数!
?
?
文件载入
载入流程
php对代码的编译是以源文件为单位!
?
在执行到 require类的载入语句时,才会读目标文件内的源代码做编译,执行处理!
?
在编译载入某个文件的代码时,
只会对 require语句是否合法做判断,不会对equire.php内的语法做判断。直到执行到require 语句时,才会载入require.php内的源代码,做编译执行!
?
?
在载入某个文件时:
先退出当前的php模式。
再,载入目标代码,编译执行
最后执行完毕后,再回归到php模式中!
例如:
?
?
requirepk include
require_oncepkinclude_once
在载入文件失败时(文件没有找到)。
对文件的依赖不一样,载入失败后,触发的错误不一致!级别不同!
require会触发一个致命错误,会导致脚本终止
include会触发一个警告错误,脚本继续运行!
?
?
requirepkrequire_once
includepkinclude_once
?
带once指的是加载一次。
在执行加载时,带once的会先对当前文件是否已经加载的了该文件做一判断。
已经加载:不会再次加载
没有加载:执行加载!
require
?
_once:
?
?
怎么选择?
尽量使用 require 即可!
?
return,被载入文件内的return
除了代码重用,文件载入还有一个意义:
php文件,作为数据的容器来使用
?
此时,可以利用 return 语法,放置在被载入的文件中,将数据返回给载入该文件的代码(require,include, XX_once).此时返回数据,就作为 require载入语句的返回值出现!
?
典型的应用:配置文件系统,项目数据缓存!
?
return 除了有返回的含义外,额外的还会终止当前脚本(return所在的文件脚本)的执行!
?
控制脚本执行
终止脚本执行
die,exit,一个功能
一旦出现,脚本立即终止,无论出现在哪里所有的执行都结束!
并且可以在终止前,输出一段字符串!
?
延迟脚本执行
sleep,是脚本暂停一段时间,以秒为单位。
不是无限时间:默认的脚本的最大执行周期为30秒。可以被配置:
?
函数,function
具有特定功能的可执行性代码的即可就是函数!
abs();
函数分为:核心函数(php系统定义的),用户函数(用户脚本自定义的函数)
?
最基本的使用
声明,定义一个函数
调用,使用一个函数
函数名()。
()调用操作符。
注意
声明和调用谁在前?
声明在前。但是在编译时,函数是预先被编译形成执行代码的。因此源代码的语法上,可以出现,先调用,后声明语法顺序!
如果函数的定义,被放置在载入的文件内,则需要先载入!
?
函数的定义可以出现在其他语句块内,但是必须保证语句块执行,函数的定义才会生效!
?
函数名必须唯一
用户定义的不能相同,用户定义的不能与系统的重名
?
?
函数的组成:三部分:函数名,函数参数,函数体。
函数名
函数的标识符,调用函数
大小写不敏感!
典型的命名方法,驼峰法!单词的首字母大写,第一个单词除外!
?
可变函数
函数的标识符(函数名),可以由一个变量来充当!意味着可以出现:
$func();
作用在于:
可以动态确定当前所调用的函数名字!
例如:在处理图片时,会用到:
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromgif
功能相同,但是细节(图片类型)不同。
?
匿名函数
php5.3增加!
匿名,没有名字。php允许存在没有名字的函数,称之为匿名函数!
基本语法
声明
与普通函数相同,没有名字部分
匿名函数的管理方式,不同于普通函数,类似于值(数据)的管理方式!将其保存在一个变量内!
?
匿名函数,是一个内置的Closure类的对象。
php的匿名函数如何实现的?
利用Closure类的对象实现!
tip:closure闭包的意思,导致,php的匿名函数也称之闭包函数!
?
调用
直接调用该匿名函数对象即可!
注意区分好可变函数。变量的内容加以区分。
变量值为字符串,作为可变函数。
变量值为Closure对象,为匿名函数。
?
函数的参数
提供,函数运行时所依赖的数据!
形参,实参
形参,形式参数,函数声明时,用于表示函数需要哪些参数的语法,称之为形参!函数内部通过处理形参,完成逻辑功能!
实参,实际参数,函数被调用时,实际获得的参数数据,称之为实参!
?
形参的值,最终是调用函数时,实参为其传递过来的!
谁调用,谁传参!
定义函数时,不用考虑参数来源问题!
?
?
调用时,发生了一个实参为形参赋值的过程!
此时,如果实参也是一个变量!
就相当于,发生了一个,实参变量为形参变量赋值的过程!
两个变量间的赋值,出现了值传递,和引用传递的区别!
$name = $real_name;//值传递
$name = & $real_name;//引用传递
值传递,引用传递
默认的,是值传递:
?
可以在实参前,增加&,取引用符号,实现引用传递!
?
注意,上传的传递引用的方法:
sayHello(&$real_name)
会触发一个错误:是过期的语法一个错误
现在,声明一个函数的参数为引用传递,应该在形参上做处理:
如果一个参数需要被引用传递,则在形参前,增加引用符号即可!
?
注意,一旦引用传递,则在调用时,只能使用变量作为实参!
?
tip:手册中,如果一个参数是引用传递,则表示方式为形参前有&
?
参数的默认值
如果在调用函数时,没有为函数传递参数,则参数可以指定默认值!
一般用于,参数经常性是某个值时,可以将其设置成默认值,在调用时,省略掉常用的参数!
注意:
- 默认值一定要是一个固定值,或者一个常量。不能是变量!
可以是常量
只要在调用之前,常量值确定,则可以使用!
- 如果在参数列表内,有部分参数存在默认值,但是部分不存在,则将存在默认值的参数,放在形参列表后边完成!
?
?
参数的个数
形参个数与实参个数之间的关系
?
形参:函数运行时需要的
实参:函数运行时得到的
?
得到的需要大于或者等于需要的!
形参数量多于实参数量
触发一个警告错误
形参数量少于实参数量
正常
?
不定参数函数
不定的参数的个数!
典型的,一个参数也不定义!
此时,调用时所传递的实参,也被传递到的函数内部!此时可以使用php的内部函数
func_get_args()//args arguments 实参
得到函数的所有的实参!
?
?
函数体
函数中最重要部分。是执行代码的集合!
?
return语句函数的返回值
返回值return
函数的处理结果,可以返回给调用函数的位置
?
注意
函数只能有一个返回值,但是可以有多条return语句!
?
返回值也分:值返回,和引用返回!
参数的引用传递
return语句,取得值,将其返回!
在函数上做处理,给函数增加返回引用的功能:
语法上:
在定义函数时,在函数名前面增加一个&引用符号!
表示:该函数,可以返回引用!
此时,函数的返回值,return后一定要是一个变量!
?
还需要,在调用函数时,取得该函数返回的引用!
?
作用域,变量作用域
作用域,起作用的区域。只有变量才有作用域的概念!
?
对于用户脚本来说,共两种作用域。局部,全局
?
全局
:函数体外,称之为全局。
局部
:函数体内,称之为局部。
?
作用域是不可重叠的,不同作用域之间的变量,不可以互相访问!
?
?
除了以上的作用域变量(用户脚本,用户自定义的变量),php还提供额外的预定的变量!
$_GET,$_POST 这些变量的作用域时超全局的!
超全局
既可以在函数外,也可以在函数内!
强调:只有预定义的超全局变量,没有用户定义的超全局变量
?
如何跨作用域访问数据(不是变量)
借助于已经存在的预定义超全局变量!
问题:
计算商品价格:
获得原始价格,将其打8.5折,在去掉用户所拥有的积分抵消,在加上运费
以上四个功能利用4个函数完成,需要共享价格数据!
此时需要一个数据,在多个函数之间进行传递!
?
没有超全局的用户变量,但是超全局的用户数据!
将用户数据,作为元素,存放到预定义的超全局数组变量完成!
?
$GLOBALS
预定义变量$GLOBALS就是专门用户数据超全局化的一个预定义变量!
?
不同于其他的超全局变量:
每个全局变量,自动地与 $GLOBALS内的一个元素相对应。
增加一个全局变量,则自动在$GLOBALS内增加一个同名元素!反之亦然!
?
甚至,删除也是一样!
?
因此,不用手动增加元素:
在函数内,范围全局变量,直接使用$GLOBALS即可
如果想在函数内,增加一个全局变量,如何处理:
?
global
还有一个 global的关键字。
功能是,在函数内访问全局变量!
?
此时,并没有将$v5超全局。
global的作用是声明一个局部变量,并将其初始化为同名全局变量的一个引用!
?
测试:
?
变量的生命周期
?
php中任何的数据资源(变量,常量,等等),最大生命周期都是脚本周期结束!
?
局部变量的生命周期
默认的,一个局部变量从声明时开始,到当前函数运行结束!
?
静态局部变量
静态的局部变量,也是局部变量!作用域也是在某一个函数内!
?
静态,指的是,在函数运行结束后,值不被释放!而是被保留。下次调用该函数时,可以继续使用!
使用关键字 static声明!
?
可以选择,在声明静态变量时,对其初始化!初始化,只运行一次!
?
?
返回引用可以看到了
?
预习
函数的递归调用
匿名函数
函数相关函数与魔术常量
数组遍历,数组函数
作业
- 测试题,测试魔术常量的值是什么?
例如:a.php中载入了b.php。而在b.php中,我输出 echo __FILE__。此时的输出是哪个文件的地址?类推 __DIR__, __LINE__呢?
?
- 定义一个函数concat()可以完成多个字符串的连接操作!
?
3, 做一个进制转换的计算器。
可变函数测试:一个数组元素是否可以充当一个函数名
$arr[key]();
?
4, 求某个数是否为素数。
????判断N之内的素数!
参见筛选法求素数!
?
作业说明
?
- 魔术常量的处理方式
类似一个字符串值替换的过程!
魔术常量不是常量,语法上类似常量,称之为魔术常量!
?
- 被载入文件内的变量的作用域问题
取决于被载入的位置。全局载入就是全局变量,局部载入就是局部变量!
?
- 不定字符串数量的连接
?
explode,将一个字符串,利用某个分隔符,切割成数小块,放在数组内!
数组 = explode(‘分隔符‘, 字符串)
?
?
如果需要为一个函数传递未知的参数,可以利用php的内置函数:
调用函数的返回值 = call_user_func_array(‘函数名‘, 参数数组);
调用一下所指定的函数名函数,并将数组内的元素,作为函数的参数调用!
?
还有一个:
调用函数的返回值 = call_user_func(‘函数名‘,$p1, $p2, …)
?
- 可变函数
函数的递归调用
函数体内,再调用函数本身,称之为递归调用!
?
一个大问题,可以拆解成多个小问题。同时大问题,与拆分的小问题的解决方案一致!典型需要在调用函数解决大问题时,内部再调用该函数去解决拆分的小问题,就形成的递归调用!
?
例如:我们需要解决斐波纳挈数列:
前两项已知(典型的是1,1),从第三项开始,每项为前两项的和
1????1????2????3????5????8????13????21????34????55????89
?
定义函数,完成计算求得第N项斐波纳挈数列的值!
f(3) = 2;
f(5) = 5
f(10) = 55
典型:
f(1) = 1, f(2) = 1;//前两项已知
f(n) = f(n-1) + f(n-2);//n>=3
?
f(10) = f(9) + f(8);????f(9)=f(8) + f(7); f(8)=f(7) + f(6)
?
递归编程,语法上就是函数体内调用函数:
存在两个要点:
- 递归点:什么时候递归调用。
- 递归出口:什么时候不用递归调用。
?
f(n) = f(n-1) + f(n-2);
递归点:
递归出口:n<=2时,已知,不需要在递归调用!
?
?
模拟下上的函数的递归执行过程!
?
采用迭代法解决斐波纳挈数列
迭代,不是语法,算法的一个概念!
将一个步骤,重复地执行,直到问题解决:
迭代的语法体现,就是循环结果!
?
?
再次解决斐波纳挈问题:
?
1????1????2????3????5????8????13????21????34????55????89
1 |
1 |
2 |
3 |
5 |
8 |
13 |
21 |
34 |
55 |
89 |
? | ? | ? |
前二项 |
前一项 |
2 |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
? |
前二项 |
前一项 |
3 |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
? | ? |
前二项 |
前一项 |
5 |
? | ? | ? | ? | ? | ? | ? | ? | ? |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
? | ? | ? | ? | ? | ? | ? | ? |
前二项 |
前一项 |
89 |
? | ? | ? |
????
?
?
?
?
注意概念:
算法描述 |
语法体现 |
? |
迭代 |
循环 |
? |
递归 |
函数内调用函数本身 |
? |
分治算法(分而治之) |
? | ? |
? | ? | ? |
?
关于函数的函数
call_user_func_array()
call_user_func();
?
function_exists();?判断一个函数是否被定义了
?
?
?
?
create_function(),创建一个函数,通过内置的函数的形式,自动完成函数的创建!
函数名 = create_function(‘参数列表‘, ‘函数体内容‘);
?
此时,可以根据当前的业务逻辑,完成函数的创建:
大家可以采用三种方法得到函数:
- function创建一个普通函数
- function声明一个匿名函数
- 使用create_function来创建函数!有函数名!
?
?
魔术常量,__FUNCTION__
在函数,获得当前的函数名的魔术常量!
?
匿名函数
没有名字的函数
是 Closure类的对象,实现匿名函数的基础!
在管理一个对象(数据)。
?
USE语法
use,可以使得匿名函数内部,来使用匿名函数外部作用域变量的数据!
注意,不是找全局,而是找外部!
?
?
use 使用的变量,也分为引用传递和值传递!
默认是值传递:
?
可以改成引用传递:
测试:
?
典型的匿名函数可以作为临时函数来使用!
例如,有些内部函数,需要调用某个函数来完成操作!像:array_map();
返回数组 = array_map(‘函数‘, 数组);
对某个数组内的所有元素做利用提供的函数做操作!
此时可以利用匿名函数完成:
凡是参数需要 callback(callable)地方,都是通过传递匿名函数完成!
注意,callback类型的参数,可以放置一个函数名,可以放置一个匿名函数,还可以放置一个create_function的结果!
?
数组
数组分类
关联数组,索引数组
按照键与值之间的关系
?
关联数组:键值之间有对应关系,键表示其值的含义!
?
索引数组:表示一个数据的集合,每个元素之间是平等的,此时元素的键仅仅表示该元素的位置,而不去表示该元素的含义!
典型的索引数组,应该下标从0开始,逐一递增的!
注意:
不是下标为数值,就为索引!例如下面:
学号与姓名是一一对应的,也是关联数组!
?
一维数组,多维数组
按照元素的值,是否是数组类型划分的
并不要元素的内容一致!
多维数组,不是行列的概念,而是倾向于递归的概念!
?
php的数组,是一个键值对的集合(列表),只是键和值的类型不同而已。
?
以上的分类,是站在使用(业务逻辑)的角度分类的!
?
其中,典型的二维数组,熟悉其结构!
大家操作的数据库,都是关系型数据库,关系型,就是一张二维表,有行有列!
?
?
例如count函数,是获得数组元素的个数!
注意,接收第二个参数,表示是否递归统计元素个数的含义!
?
数组遍历
依次得到每个数组元素信息,分别操作。称之为数组遍历
?
for遍历索引数组!
数组指针
思考:
遍历:????依次获得数组元素信息(键和值)
//先确定了下标(键),再下标访问元素
?
for是先确定下标,再获得元素!
?
真正的遍历,一定是先确定元素,再获得元素的键值信息!
?
基本实现是:数组元素指针!
每个数组内,都存在一个指针,某一时刻,指向数组内的某个元素上!默认的指向第一个元素!
?
同时:php有:获得指针指向的数组元素的键和值的能力!
利用函数
current(),获得当前元素的值
key():获得当前元素的键。如果指针已经非法,返回NULL。用来判断是否存在元素了
还应该有:将指针移动的能力!
next()函数,可以完成指针的移动!
?
配合上循环结构即可完成数组的遍历:
?
?
foreach循环结构
语法
?
可以省略键:、
?
流程
?
使用foreach的注意事项
- 修改$value 是不会影响到原数组的值的!
键变量一致!
?
- 保存值的变量,支持引用传递。
在$value 前增加&。
修改 $value 会影响到原数组
键变量不能引用传递
?
- foreach遍历的是原数组的拷贝,而不是在原数组上做的操作
在遍历的过程中,如果对原数组做操作,是不会影响到遍历结果的
- foreach也是一个循环结构:
break,continue,替代语法都存在!
?
foreach为遍历数组准备的循环,尽量使用foreach完成遍历!
?
?
数组指针的操作
利用php的内置函数:
key,
current
next();
prev();移动到上一个
reset();//重置,移动到第一个元素
end();//移动到最后一个元素上
注意一旦指针位置非法,则不能做相对移动(next,prev),可以绝对移动(reset,end)
reset,使用频率较高!
?
each(),集合了 key,current,和next三者的功能!将当前元素信息获得后,移动指针到下一个元素上!
元素信息数组 = each($arr).移动指针
注意,元素信息数组,是两种表示方案:索引和关联:其中:
索引:0,1分别表示键和值
关联:key,value分别表示键和值
?
?
each+while+list遍历数组
list-each遍历数组
?
升级:
将获得键变量和值变量的操作,简化!
?
利用 list结构
利用一个索引数组,同时初始化多个变量!
?
each的返回值就包含了索引数组
0为键,1为值!
利用list简化的结果:
?
?
其实:只要有循环结构,指针操作就可以完成遍历数组
?
预习
数组的复制,指针的复制规律,foreach与数组指针的关系
介绍常用的数组函数
?
进入mysql数据库讲解
sql,库操作,表操作,数据操作。
php操作mysql,详细介绍
?
作业
- 思考题,上台阶问题
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
你,只能一步,上一级,或者两级!
问题是:如果该台阶 50 级。上台阶一共多少种方案!
?
- 编程题
猴子吃枣。吃了一半(一堆的一半),不过瘾,又吃了一个!每天都这么吃。第十天时,还想吃,发现只有一个了!
问题:计算出来每天有多少枣子!
要求:分别采用递归和迭代分别实现!
编写两个函数,一个是递归的,一个是迭代!
?
- 使用for,模拟foreach。
?
?
- 记录乘法表的结果。(模拟的缓存系统)
1*1=1
2*1 = 2 2*2=4
?
4*5
记录的值和位置
使用二维数组
$data[4][5] = 20;
?
$i=4, $j=5;
echo $data[$i][$j];
?
- 杨辉三角
对角线和第一列值为1,其他值为头顶+左肩之和
数组的指针问题讨论
拷贝时
考虑复制时的指针位置问题:
?
指针位置,随之复制!
?
如果原数组指针已经非法了呢?
再看:
?
问题是,复制后,谁先执行的current,哪个数组指针被初始化!
该现象的原因是:
?
- 如果数组指针位置非法,复制时,会将新数组指针初始化!
- 值传递时,PHP采用了一个 COW(写时复制,copy on write)的优化措施!
写时复制的两个要点:
one,在值传递时,并没有马上为新变量开辟值空间,而在两个变量都未发生改变之前,还是使用的一个值空间
two,一旦某个变量发生改变,此时会复制值空间,让发生改变的变量去引用新的空间!
?
?
注意,current也会发出写操作,导致空间被复制!先current谁,谁是那个新的,指针被初始化!
?
?
?
foreach时
?
- 遍历的是拷贝而不是原数组!
- 只有在原数组发生写操作时,才会真正的拷贝。此时原数组指针停留在当前位置,如果已经非法,则会初始化!
?
?
数组函数
range()函数,可以得到某个范围内的元素数组:
?
array_merge(); 数组合并,合并多个!
下标重复会怎么样?
数值索引:完全重新索引!
字符下标:后出现的元素值会覆盖前面的元素值!
?
?
array_rand(数组,个数);随机地从数组内取得元素,取得是下标!
如果多个,返回随机下标的集合!
结果是被排序之后的,从小到大!
?
shuffle(&$arr).打乱数组内元素的顺序
注意,参数为引用传递!会打乱原数组
典型的还要遍历,获得所有的值!
?
键值操作
array_keys(); 取得所有的键
array_values();取得所有的值
?
in_array();是否存在某个值
array_key_exists();某个键是否存在
判断某个元素是否存在,典型的是使用isset()来判断
?
array_combine();利用两个数组合并成一个数组,其中一个作为键,另一个作为值!
?
array_fill();填充数组
数组 = array_fill(起始下标,填充的元素个数,填充的值);
?
拆分合并
array_merge()
array_chunk();拆分数组,原则是子数组内的元素个数!
?
explode(),将字符串依据某个分隔符,分割成多个数组
implode(),将数组内的元素,利用某个分隔符,连接成一个字符串!
字符串函数:
?
array_intersect($arr1, $arr2);计算两个数组的交集,找到在$arr1中存在,并也在$arr2中存在的元素,数据是出现在第一个参数中的:
array_diff($arr1, $arr2);计算两个数组的差集。找到在arr1中存在,但是在arr2中不存在的元素!
?
?
模拟桟和队列
桟和队列都是典型数据结构,都是 list 列表的一种!
?
桟:先进后出
?
入栈:array_push,在桟尾放入元素!
出栈:array_pop
数组是引用传递
?
?
与删除元素与增加元素使用[]不同,array_push与array_pop会重新索引,保证所有的元素都是由0开始的逐一递增!
?
队列,先进先出
?
?
入队列:array_push()在数组的尾端将数据压入数组
出队列:array_shift();在数组的顶端,将数据取出
?
?
?
?
?
?
array_unshift()可以将数据由数组的顶端压入数组!
?
可以使用回调函数
array_map
?
可以针对数组的每一个元素的值,去调用某个函数!比较适合索引数组的处理!
典型功能:
一次性处理多个数组,可以同时将多个数组的同位置的参数,传递到一个函数内!
处理多个数组时,默认操作是将三个数组合并成一个数组!形参一个二维数组!
?
array_walk
类似于foreach
?
排序类
升序,降序
按照键,还是按照值
是否保持原有键值关联
sort(),按照值,升序,不保持键值关联
排序函数都是引用传值!
?
ksort()按照键,升序
k key 键
rsort()按照值,降序,不保持关联
r reverse 反转
krsort();按照键,降序
asort按照值,升序,保持关联
a association 关联
arsort按照值,降序,保持关联
?
natsort()自然数排序
可以利用计算出来的自然数,对数据进行排序!
?
usort()自定义排序
u user 用户自定义,用户自定义的元素之间的大小关系!
用户提供一个比较两个元素大小的函数了,并可以告知php元素的大小关系!
此时,用户所定义的函数,负责告知usort,两个元素之间的大小关系,而usort得到关系之后,负责完成排序!利用返回值告知!
升序的返回效果:
返回负数,表示第一个元素小
返回正数,表示第一个元素大,
返回0,表示相等
?
降序的返回结果:
返回负数,表示第一个元素大
返回正数,表示第一个元素小
返回0,表示相等
?
?
典型的排序算法:
冒泡,快速(不同的编程实现),桶式排序,选择,插入,希尔..
?
?
素数编程
判断是否为素数
?
得到平方根:
?
sqrt()
?
得到N之内的素数
?
?
筛选法
假设每个数都是素数。例如,素数使用1表示,非素数使用0表示
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
? | ? |
0 |
? |
0 |
? |
0 |
? |
0 |
? |
0 |
? |
0 |
? |
0 |
? |
0 |
? |
0 |
? |
0 |
? | ? | ? | ? |
0 |
? | ? |
0 |
? | ? |
0 |
? | ? |
0 |
? | ? |
0 |
? | ? |
0 |
? |
2 |
3 |
? |
5 |
? |
7 |
? | ? | ? |
11 |
? |
13 |
? | ? | ? |
17 |
? |
19 |
? | ? | ? |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
?
?
拿 2 筛选,所有2的倍数全部为非素数
拿 3 筛选,
选数的原则,已有素数!只拿标识为1的数作为筛选数!
一直到,最大数的平方根即可!
?
编程实现:
完成一个所有数的标识!
?
开始筛选
?
选择筛选数!
从2开始到最大数的平方根,内的所有已知素数(标识为1)
筛选即可
?
?
?
测试效率,使用函数
microtime(true),可以得到当前的时间戳,的微秒形式!
参数表示是否返回浮点数!
从1970到现在的秒数!
?
?
?
内存错误:
可以通过配置修改:
作业
1,杨辉三角:
?
2测试cow的效果!
?
- 计算相对路径
$path1 = ‘e:/php1016/a/b/c/d/file.php‘;
?
$path2 = ‘e:/php1016/a/f/new.php‘;
?
require‘../../../f/new.php‘;
计算两个路径的相对路径$path2,$path1的路径
?
tip:桟
?
explode
?
?
?
?
?
?
?
?
asort
array_insertsect
array_map();
array_merge()
array_diff()
array_rand();
array_walk()
array_fill()
krsort()
shuffle();
ksort();
usort();
rsort();
arsort();
count()
array_values()
explode();
implode();
?
array_push();
array_pop();
?
array_unshift();
array_shift();
?
?
empty(0)????true
?
(bool) 0????false
?
empty(‘‘); true
(bool) ‘‘; false
?
?
strrpos()取得某个子字符串最后出现的位置
substr(待截取字符串,起始位置,截取长度)截取字符串,
?
?
?
?