include 和 require
/**
include include_once
require require_once
**/
// 比如 我们经常要连数据库
// 那么,下面这这句话就要经常出现
// $conn = mysql_connect('localhost','root','111111');
// 比如共出现了8次,还有一个坏处
// 就是,如果用户名/密码变了,则要改8处.
// 可以把这段代码 写在一个公共文件里, 然后包含公共文件.
include('./conn.php');
echo $age,'<br />'; // 27
echo $name;
/*
怎么来理解 include/require
就相当于, 把conn.php的代码,复制粘贴,代替 include那一行.
注意: include/require 包含进来的文件必须要加<?php ?>
因为在包含时,首先理解文件内容是普通字符串,
碰到<?php ?> 标签时,才去解释
*/
require('./req.php');
echo $name,'<br />';
echo $age,'<br />'; // 28
/*
./req.php中的 ./是什么意思?当前目录
这是相对路径
也可以用绝对路径,即用盘符指定
*/
/*
绝对路径 也可以包含
在win下,路径可以用正斜线,也可以反斜线
而在linux下,则只能用正斜线 /
因此: 用正斜线 /
*/
require('D:/www/1015/req.php');
echo $name,'<br />';
echo $age,'<br />'; // 29
?>
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
// include 和 require的区别
/*
共同点:都能用来包含文件
不同点:
*/
echo 'a<br />';
include('./dsafds.php');
echo 'b<br />';
require('./dsafds.php');
echo 'c<br />';
/*
打印结果
a
warning
b
fatal error
c没打出来
这说明:
include 是包含的意思
在找不到包含文件时,会报warning, 然后试着往下运行.
require 是必须的意思
在找不到包含文件时,会报fatal error, 然后不再往下运行.
*/
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
// include/require(_once) ,即 _once的区别
$age = 5;
/*
include('/04.php');
echo $age; // 6
include('/04.php');
echo $age; // 7
include('/04.php');
echo $age; // 8
*/
include_once('04.php');
echo $age;// 6
include_once('04.php');
include_once('04.php');
include_once('04.php');
echo $age;// 6
/*
加once后,则在包含时,系统会进行判断
如果已经包含,则不会再次包含.
*/
/*
include require的取舍:
比如,是系统配置,缺少了,网站不让运行,自然用require
如果,是某一段统计程序,少了对网站只是少统计人数罢了,不是必须要,可以用include
include/require --> _once
则是效率上区别
加_once虽然系统帮你考虑了只加载一次,但系统的判断卖到效率降低.
因此,更应该在开发之初,就把目录结构整理好.
尽量不要用_once的情况.
*/
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
/*
下面这个用法,是利用 include /require返回被包含页面的值
被包含页面A中 return value
包含页面B中 $v = include('A.php');
则 $v 被赋值为 value
这个用法,在网站做配置文件时,会偶尔碰到
比如TP的配置文件
*/
$arr = include('./array.php');
print_r($arr);
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
echo '<pre>';
// sql的注入与转义
/*
先下如下例子:
del.php?id=3
$sql = 'delete from news where id=' . $_GET['id'];
del.php?id=3 or 1;
这时 $sql = 'delete from news where id=3 or 1'
这样,所有的新闻将都被删除.
*/
/*
addslashes 可以对某个变量转义,
但是,$_POST是一个数组,可能有多个单元,
如果每个单元手动的addslashes来转义,工作量大.
有什么办法,可以对$_POST数组的每一个单元,进行转义?
*/
/*
// 插播一个小题目
$arr = array(1,2,3,4);
// 用foreach来处理$arr
foreach($arr as $v) {
$v *= 2;
}
print_r($arr);
foreach($arr as $k=>$v) {
$arr[$k] = 2 * $v;
}
print_r($arr);
*/
// 回到$_POST上来,要循环对POST做转义
$_POST = array('age'=>28,'name'=>'abc"');
foreach($_POST as $k=>$v) {
if(is_string($v)) {
$_POST[$k] = addslashes($v);
}
}
print_r($_POST);
// 但是----
$_GET = array('id'=>5,'gender'=>'m"','user'=>array('name'=>'lisi','area'=>'bj"'));
foreach($_GET as $k=>$v) {
if(is_string($v)) {
$_GET[$k] = addslashes($v);
}
}
print_r($_GET);
/*
Array
(
[id] => 5
[gender] => m\"
[user] => Array
(
[name] => lisi
[area] => bj"
)
)
gender m" 被转义了
而area bj" 没被转义
因为 user单元又是一个数组,没有进去处理 .
此时,已经用到了递归的思想.
*/
// 我们用系统提供好一个函数,来对数组进行递归
// array_walk_recursive ,这是递归处理数组单元的函数
// 函数本身只有一个功能------递归的把数组每个单元走一遍
// 至于你怎么处理这个数组,自己写一个函数,
// 然后 array_walk_recursive会带着你写的函数把数组单元走一遍.
// 如下,array_walk_recursive带着addslashes在数组各单元走一遍,
// 自然,各单元都被转义了.
function abc(&$v,$k) {
$v = addslashes($v);
}
array_walk_recursive(&$_GET,'abc');
print_r($_GET);
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
/*
PHP中,有一个魔术引号的概念,
如何打开?
答:在PHP.ini中,magic_quotes_gpc=On;
重启apache即可
然后做下面的实验
发现$_GET被自动转义了.
这是魔术引号的作用---魔术引号开启时,$_GET,$_POST,$_COOKIE数据,会被系统自动转义.
*/
print_r($_GET); // 此时已被系统转义了.
function abc(&$v,$k) {
$v = addslashes($v);
}
array_walk_recursive(&$_GET,'abc');
print_r($_GET); // 到此处,第二次转义,转多了.
/***
要想合理的转义,得先判断 魔术引号 有没有开启
如果开启了,不要再转义了,
如果没开启,再转义.
问:如何判断魔术引号没有开启?
答: 用magic_quotes_gpc()来判断
***/
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
// 合理的判断及转义
if(!get_magic_quotes_gpc()) { // 如果魔术引号没开
function _addslashes(&$v,$k) {
$v = addslashes($v);
}
array_walk_recursive(&$_GET,'_addslashes');
array_walk_recursive(&$_POST,'_addslashes');
array_walk_recursive(&$_COOKIE,'_addslashes');
}
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
/*
PHP在运行时, 针对严重程度不同的错误,给以不同的提示,
*/
/*
比如,下面程序,在$a没声明时,直接相加,值为NULL,相加时当成0来算.
但是,却提示NOTICE,即注意.
*/
$b = 3;
echo $a+$b; // 3
/*
我们在开发中, 为了程序的规范性,把报错级别,调的比较高
NOTICE级别的也报出来,有助于我们快速定位错误和代码规范
但是,在产品上线后,网站运营过程中,就不宜报这么多错.
1:这种错误给客户的印象不好
2:在报错时,把网站的绝对路径,如D:\www\1015都报出来了.
增大被攻击的风险
因此,在网站上线后,就应该让报错级别低,少报错甚至不报.
*/
// 如何来调 ,见下一页
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
/*
1: php.ini里修改error_reporting 选项
2: 可以在php页面里,用error_reporting()函数来修改
*/
/*
错误级别用2进制的值来表示的
1111 1111 1111 111
从左到右,每位上的1,代表一种错误级别
*/
/*
fatal error致命错误: 0000 0000 0000 001 开启
warning 警告错误 : 0000 0000 0000 010 开启
NOTICE 警告 : 0000 0000 0001 000 开启
*/
/*
error_reporting(11);
echo $a+$b; // notice报出来
echo 3/0; // warning报出来
echo dsafdsa(); // fatal报出来
*/
// 不要报NOTICE了
/*
error_reporting(3);
echo $a+$b; // notice不报了
echo 3/0; // warning报出来
echo dsafdsa(); // fatal报出来
*/
// 来点狠的,任何错误都不错
/*
error_reporting(0);
echo dsafdsa(); // fatal不报
echo $a+$b; // notice报出来
echo 3/0; // warning报出来
*/
// 报所有错误,
// 我们不必去通过2进制去算了
/*
系统为我们把各个级别的值,用系统常量代替了.
E_ERROR 1
E_WARNING 2
E_NOTICE 8
*/
// 报所有错误
/*
error_reporting(E_ALL);
echo $a+$b; // notice报出来
echo 3/0; // warning报出来
echo dsafdsa(); // fatal报出来
*/
// 报除了notice之个的所有错误,即除了NOTICE,其他都报.
error_reporting(E_ALL & ~E_NOTICE);
echo $a+$b; // notice不报
echo 3/0; // warning报出来
echo dsafdsa(); // fatal报出来
/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/
// 在开发中,报错级别高一点
// 在上线产品中,报错级别要低
define('DEBUG',true); // 在开发时,声明一个DEBUG模式
if(defined('DEBUG')) { //检测到处于开发模式
error_reporting(E_ALL);
} else {
error_reporting(0);
}
echo $a+$b; // notice不报
echo 3/0; // warning报出来
echo dsafdsa(); // fatal报出来
<?php
return array('a','b','c','d');
<?php
$age = 27;
?>
<?php
$name = '张三';
$age++;
?>
浙公网安备 33010602011771号