一、 演示函数中引用外部变量的5种方法
PHP作用域:
不支持块作用域
支持函数作用域
// 实例:不支持块作用域
if(true){
$a = 100;
}
echo $a.'<br>';
js中函数可以直接访问函数外的变量
php中不行
运行结果:
问题一 函数如何引用外部变量?
五种方式来解决:
- 关键字global方式引用外部变量。
- 超全局数组方式引用。
- 匿名函数/闭包方式将外部变量导入。function()use ($variable)
- 箭头函数方式引用(不建议用在生产环境)
- 纯函数方式,通过函数参数引入。
关键字global方式引用
$name = '路人甲';
error_reporting(E_ALL);
function get_name():string {
global $name;
return 'Hello' .$name;
}
echo get_name(),'<br>';
运行结果:
超全局数组方式引用
$name = '路人甲';
error_reporting(E_ALL);
function get_name():string {
global $name;
return 'Hello' .$GLOBALS['name'];
}
echo get_name(),'<br>';
匿名函数/闭包方式将外部变量导入,要有use否则报错。
$name = '路人甲';
error_reporting(E_ALL);
$get_name = function () use ($name):string {
return 'Hello'.$name;
};
echo $get_name(),'<br>';
箭头函数方式引用
$name = '路人甲';
error_reporting(E_ALL);
$get_name = fn() => 'Hello'.$name;
echo $get_name(),'<br>';
纯函数方式引入
$name = '路人甲';
error_reporting(E_ALL);
$get_name = function($name):string{
return 'Hello'.$name;
};
echo $get_name($name),'<br>';
问题二 外部如何引用函数私有变量?
$name = '路人甲';
error_reporting(E_ALL);
$get_name = function() {
$private_name = '路人乙';
// 通过返回值返回数组,夹带私货,把函数内部变量导出。
return ['Hello', $private_name];
};
//这种方式可以,但是不好,可以使用解构方式。
// echo $get_name()[0],$get_name()[1].'<br>';
// 将数组成员解构到独立变量中
list($say, $priv_name) = $get_name();
// 上面一行等同于: list($say, $priv_name) = [$get_name()[0],$get_name()[1]];
echo $say, $priv_name, '<br>';
问题三 函数内部私有变量和外部变量同名时会怎么处理?
$name = '路人甲';
error_reporting(E_ALL);
$get_name = function() use ($name) {
// $name = '路人乙';
// 通过返回值返回数组,夹带私货,把函数内部变量导出。
return 'Hello'. $name;
};
// 函数内部变量会覆盖外部同名变量
echo $get_name();
常量
- 声明
define和const定义常量。大写且不用“$”符号。
define是函数,可用在if中,不能用在类中。
const在编译阶段处理,速度更快,必须在作用域顶部声明。
常量不收作用域限制,全局有效。 - 查看
echo
constant - 类型
自定义
预定义(不可变,可变(魔术常量))
//------------自定义常量----------------
define('USER_NAME', 'admin');
const EMAIL = 'admin.php.cn';
echo USER_NAME.','.EMAIL.'<br>';
function hello():string{
return sprintf('Hello,%s,(%s)',USER_NAME,EMAIL);
}
echo hello().'<hr>';
echo USER_NAME;
echo constant('USER_NAME');
// constant不能打印const定义的常量
// echo constant('EMAIL');
// 空字符可以当常量名
define('','php中文网');
//constant可以打印空字符常量用于特殊用途
echo constant('');
//------------预定义常量----------------
echo 'php版本:'.PHP_VERSION.'<br>';
echo '操作系统:'.PHP_OS.'<br>';
// 预定义常量的子集:魔术常量
// 他是变化的,是系统自动赋值和维护更新,用户不能修改(只读)。
echo '当前行号:'.__LINE__.'<br>';
echo '当前文件:'.__FILE__.'<br>';
echo '当前路径:'.__DIR__.'<br>';
二、字符串
1. 使用介绍
单引号
1、纯文本
定界符:单引号/nowdoc
特点:不解析变量,不转义特殊符号的转义序列
场景:静态文本,不含变量和转义符
双引号
模板字符串
定界符:双引号/heredoc
特点:解析变量,转义特殊字符
场景:包含插值变量和特殊字符的动态模板。
// ------传统单引号---------
$domain = 'https://www.php.cn';
$str = '网站名称:\n\r $domain';
echo $str.'<br>';
// ------newdoc:单引号语法糖,适合大段文本---------
$str = <<< 'ANYNAME'
<header>
<a href="">首页</a>
<a href="">视频</a>
<a href="">文章</a>
</header>
ANYNAME;
echo $str.'<br>';
// ------双引号---------
$site = "网站名称:\n\r $domain";
echo $site.'<br>';//换行效果上页面上不换行,但右键查看源代码,效果是换行的。
// ------heredoc双引号语法糖---------
// 适用大段的,多行的动态文本内容,内部有变量和大量双引号(不用转义)。
$tpl = <<<"ANYNAME"
<ul style="display: inline-grid; border:1px solid">
<li style="color: brown;">PHP中文网</li>
<li>$domain</li>
</ul>
ANYNAME;
echo $tpl;
备注
- 代码中ANYNAME是标识符,全大写是行业约定,可任意命名,需成对出现。
- nowdoc的标识符的单引号’ANYNAME’必须要写。
- heredoc的标识符的双引号是可选的,例如ANYNAME是可以的,而且推荐不加双引号。
- 更多转义序列
2. 字符串函数
// 字符串常量函数
// 1. string <-> array
// array-> string:implode($separator,$arr):string
$color = ['red','green','blue'];
echo implode('-',$color).'<br>';
// string -> array:explode($separator, $string)
$link = 'mysql:dbname=phpedu;root;root';
$dbconfig = explode(';',$link);
print_r($dbconfig);
// list解构
list($dsn,$username,$passwd) = explode(';',$link);
printf('<br>dsn = %s<br>username = %s<br>password =%s<br>',$dsn,$username,$passwd);
// vprintf打印
$db = explode(';',$link);
$tpl = '<br>dsn = %s<br>username = %s<br>password =%s<br>';
vprintf($tpl,$db);
echo '<hr>';
// 2. 查询和替换
$str = '中文网';
// -------取子串-------
// 一个中文三个字符
echo substr($str, 0, 3).'<br>';
echo substr($str, 3).'<br>';
// 反向
echo substr($str, -3).'<br>';
// -------首字符出现之后-------
$img = 'banner.png';
// '.'之后的字符串,得到结果再去掉左边的'.'
echo ltrim(strstr($img,'.'),'.').'<br>';
// 获取文件名,true表示向前获取
echo strstr($img,'.',true).'<br>';
// -------获取位置-------
echo strpos($str, '文').'<br>';
// 从第三个字符开始查找
echo strpos($img, 'n',3).'<br>';
// -------替换-------
$class = '\admin\controller\User';
// 各系统文件路径分隔符不同,可以用一个常量DIRECTORY_SEPARATOR来统一替代
//DIRECTORY_SEPARATOR太长,可以重定义
define('DS',DIRECTORY_SEPARATOR);
echo str_replace('\\',DS,$class).'.php<br>';
$bad = ['血腥','暴力','颜色'];
// 一对一替换
// $good = ['喵喵','旺旺','咯咯'];
// 统一替换
$good = ['***'];
$str = '不得带有血腥,隐藏暴力,无视颜色的内容';
echo str_replace($bad,$good,$str).'<br>';
// ------删除字符------
$str = ' php.cn ';
echo strlen($str).'<br>';
echo strlen(trim($str)).'<br>';
$str = trim($str);
echo rtrim($str,'.cn').'<br>';
echo ltrim($str,'php.').'<br>';
// html/php/js 标签都过滤掉
echo strip_tags('<?php echo \'Hello PHP\' ?><h1>php.cn</h1><script>console.log("Hello JS");</script>');
echo '<br>';
// ------URL相关------
$url = 'http://phpedu.io/0810/demo4.php?a=1&b=2&c=3';
// "?a=1&b=2&c=3"这部分叫查询字符串
echo $_SERVER['QUERY_STRING'].'<br>';
// 查询字符串转为数组
parse_str($_SERVER['QUERY_STRING'],$arr);
printf('<pre>%s</pre>',print_r($arr,true));
$arr = parse_url($url);
printf('<pre>%s</pre>',print_r($arr,true));
echo parse_url($url)['query'].'<br>';
// ------大小写------
$foo = 'HelloWorld';
// 第一个字母小写
$foo = lcfirst($foo);
echo $foo.'<br>';
// 全部大写
echo strtoupper($foo).'<br>';
// ------md5散列值------
echo md5($foo).'<br>';
// ------数字格式化------
$number = 1234.56;
// 英文千位分割
echo number_format($number).'<br>';
// ---转换字符串第一个字节为0-255之间的值---
$str = "\n";
echo ord($str).'<br>';
// ------统计出现次数------
$text = 'This is a test';
echo substr_count($text, 'is').'<br>';
// ------反转字符串------
echo strrev("Hello world!");