小白兔晒黑了

导航

 

0 概述

<?php
//整型数0
var_dump( empty(0));//  bool(true)
//双精度型数0.0
var_dump( empty(0.0));//bool(true)

//空字符串
var_dump( empty(''));//bool(true)
//字符串0
var_dump( empty('0'));//bool(true)
//布尔值false
var_dump( empty(false));//bool(true)
//空数组
var_dump( empty([]));//bool(true)
//NULL
var_dump( empty(NULL));//bool(true)
//数字 000
var_dump( empty(000));//bool(true)

//没有属性的对象????
$obj = new class{};

var_dump($obj);
var_dump( empty($obj));//bool(false)

//字符串00
var_dump( empty("00"));//bool(false)
// 空格字符串
var_dump( empty(' '));//bool(false)

?>

 

1 消除==和=的困扰

<?php
$dwarves = 12;
//会把==右边的,强制转化为左边的类型
if(  12 ==$dwarves){
    echo __LINE__;
}
//不转化数据类型的比较
if(  12 === $dwarves){
    echo __LINE__;
}
//会报错,常量数字12无法赋值
if(  12 = $dwarves){
    echo __LINE__;
}
?>

2 为变量设定默认值

<?php
$vehicles = ['cars'=>null];
$rs = array_key_exists('cars',$vehicles);
var_dump($rs);

$rs = isset($vehicles['cars']);
var_dump($rs);
$x = 75; 
$y = 25;
function addition() 
{ 
    $GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y']; 
}
 
addition(); 
echo $z;
$enperors=['秦始皇','秦二世'] ;
$defaults = array(
    'enperors'=>['Rudolf II','Caligula'],
    'vegetable'=>'celery',
    'acres'=>15
);

function aa($defaults)
{
    foreach($defaults as $k=>$v){
        if(!isset($GLOBALS[$k])){
            $GLOBALS[$k] = $v;
        }
    }

    var_dump($enperors);//NULL
}

aa($defaults);
var_dump($GLOBALS['enperors']);//秦始皇"


function bb($defaults)
{
    foreach($defaults as $k=>$v){
        if(!isset($$k)){
            $$k = $v;
        }
    }
    var_dump($enperors);//"Rudolf II"
}

bb($defaults);
var_dump($GLOBALS['enperors']);//"秦始皇"
?>

3  不使用临时变量而实现变量值的交换

<?php
$a = 4;
$b = 5;
$a = $a^$b;
$b = $a^$b;
$a = $a^$b;
var_dump($a);
var_dump($b);
$a = 4;
$b = 5;
list($a,$b) = [$b,$a];

var_dump($a);
var_dump($b);

$country = '中国';
$city  = "郑州";
$state = "河南";
$event = "富士康";
$result = compact("event", ["city", "state"],'country');
print_r($result);
?>

4 动态创建变量名

<?php
$donkeys[12] = 'cc';
$$donkeys[12] = 'aa';
var_dump($cc);

${$donkeys[12]} = 'aa';
var_dump($cc);

$donkeys = 'cc';
$$donkeys[12] = 'aa';
var_dump($cc);
${$donkeys}[12] = 'aa';
var_dump($cc);
?>

5 使用静态变量

<?php

function track_time_called()
{
    static $i ;
    $i++;
    return $i;
}

$i = track_time_called();
var_dump($i);//1
$i = track_time_called();
var_dump($i);//2
$i = track_time_called();
var_dump($i);//3

/*
在这个示例中,无论创建多少个 MyClass 的实例,staticCounter 都是同一个变量,它的值会随着每个新实例的创建而增加。而 instanceCounter 是一个实例变量,它对每个实例都是独立的。
*/

class MyClass {
    // 静态变量
    static public  $staticCounter =100 ;
    // 实例变量
    public  $instanceCounter = 100;
    public  function myFun() {
        self::$staticCounter ++;
        $this->instanceCounter++;
    }
}

$myObj = new MyClass();
$myObj->myFun();
var_dump(MyClass::$staticCounter);//int(101)
var_dump($myObj->instanceCounter);//int(101)
$myObj->myFun();
var_dump(MyClass::$staticCounter);//int(102)
var_dump($myObj->instanceCounter);//int(102)

$myObj2 = new MyClass();
$myObj2->myFun();
var_dump(MyClass::$staticCounter);//int(103)
var_dump($myObj2->instanceCounter);//int(101)

?>

 

6 在进程间共享变量

6.1 shmop

php 在进程间 共享变量

6.2 System V

<?php
exec('ipcs -m', $output);
// 输出命令执行结果
foreach ($output as $line) {
    echo $line . PHP_EOL;
}
echo '************';
echo PHP_EOL;
////////////////////////////////////////////////////////
//信号id
$semKey = ftok(__FILE__,'s');
//获取一个与我们想取得的共享内存关联的信号的句柄
$sem = sem_get($semKey,1,0644);
if($sem===false){
    die('返回信号量标识符失败');
}
//确保对信号的独占访问
$semRs = sem_acquire($sem) or die("获取信号量发生错误"); // get a handle to our shared memory segment
if($semRs === false){
    die('获取信号量失败');
}

///////////////////////////////////////////////////////
$shmKey = ftok(__FILE__, 'c' );
//1024 内存大小
//0644 权限
//获取内存
//获取共享内存片段的句柄
//内存大小。若没有提供,缺省为 sysvshm. init_mem in the php. ini,否则为 10000 字节
//返回一个共享内存段标识符。
$shm = shm_attach($shmKey, 1024, 0644) or die('打开或创建内存段发生错误');
if ($shm === false){
    die('打开或创建内存段失败');
}
//从内存中存入变量
$population_1 = shm_get_var($shm,1);

//初始化人口数据
$population_1  = intval($population_1);
$births = 2;//出生人口
$immigrants = 1;//移入人口
$deaths = 2;//死亡人口
$emigrants= 0;//移出人口
$population_1 += ($births + $immigrants - $deaths - $emigrants);

//存放变量到内存中
//shm_put_var 第二个参数必须是int类型,不支持字符串类型!!!!
$putRs = shm_put_var($shm,1,$population_1);
if(!$putRs){
    echo '添加数据失败'.PHP_EOL;
}
$hasRs = shm_has_var($shm,1);
if(!$hasRs){
    echo 'variable_key为1的内存数据不存在' .PHP_EOL;
}




$population_1 = shm_get_var($shm,1);
var_dump($population_1);



//释放对共享内存的句柄
/*$rs1 = shm_detach($shm);
if ($rs1 === false){
    echo '释放共享内存失败'.PHP_EOL;
}*/
//使用时以下3段代码的注释要去掉
/*//移除共享内存
$rs2 = shm_remove($shm);
if($rs2 === false){
    echo '移除共享内存失败'.PHP_EOL;
}

//释放信号,以便其他进程可以捕获它
$rs3 = sem_release($sem);
if ($rs3 === false){
    echo '释放信号失败'.PHP_EOL;
}
//删除信号,其他进程也不能捕获它
$rs4 = sem_remove($sem);
if ($rs4 === false){
    echo '删除信号失败'.PHP_EOL;
}*/


exec('ipcs -m', $output2);
// 输出命令执行结果
foreach ($output2 as $line) {
    echo $line . PHP_EOL;
}
echo '##############';
echo PHP_EOL;

?>

 

7 把复杂的数据类型压缩到一个字符串中

7.1 serialize和unserialize的用法

$pantry = array('糖果'=>'2 盒','黄油'=>'3 块');
if(!is_dir('tmp')){
    mkdir('tmp',0777);
}

$fp = fopen('tmp/pantry','w') or die('无法打开食品盒');
fputs($fp,serialize($pantry));
fclose($fp);

$newPantry = unserialize(file_get_contents('tmp/pantry'));
var_dump($newPantry);

 

7.2 magic_quotes_gpc 魔术引号开关 此功能php5.4之后的版本,包括5.4,不可用!!!

7.2.1 魔术引号开关的功能:

如果输入的数据有单引号 ' 、双引号 " 、反斜杠 \  、和空字符 %00 

会自动加上反斜杠,

Get/Post/Cookies获得的数据将会更安全,以防sql注入等恶意代码

7.2.2 开启此功能

在php.ini中设置

magic_quotes_gpc = On

 

7.2.3  使用方式:

$shopping_cart = array("芝麻饼干\'小饼干"=>2,
    '原味坚果'=>1,
    '鱼子酱'=>4
);
print '<a href="next.php?cart='.urlencode(serialize($shopping_cart)).'">Next</a>';

 next.php

$is = get_magic_quotes_gpc();
var_dump($is);

$cart = $_GET['cart'];
var_dump($cart);

$cartOn = unserialize($cart);
var_dump($cartOn);

结果

 直接用unserialize解码会返回错误

这时需要使用stripslashes函数先去掉多余的反斜杠

$cartOff = unserialize(stripslashes( $cart));
var_dump($cartOff);

即可正确解析:

 最佳使用方式:为了代码的通用性:

function stripslashesed($content)
{
    if (get_magic_quotes_gpc()) {
          return  stripslashes($content);
    }
    return $content;
}
$cartNew = unserialize(stripslashesed($cart));
var_dump($cartNew);

 

7.3 magic_quotes_sybase 魔术引号开关 此功能php5.4之后的版本,包括5.4,不可用!!!

7.3.1 功能:

magic_quotes_gpc差不多,转义结果略有差别

7.3.2 使用方法:

echo '<br />';
$gpc = get_magic_quotes_gpc();
var_dump($gpc);
//http://localhost/5-07.php?a=%27%22\%00
$a = $_GET['a'];
echo $a;

 

7.4 magic_quotes_runtime 魔术引号开关 此功能php5.4之后的版本,包括5.4,不可用!!!

7.4.1 功能

如果输入的数据有单引号 ' 、双引号 " 、反斜杠 \  、和空字符 %00 

方便 从文件中读取的数据 或 从数据库查询得到的数据时 合理解析。

7.4.2 启用方式

在php.ini中设置

magic_quotes_runtime = On

7.4.3 使用方式

7.4.3.1 读取文件

//查看是否开启
$runtime = get_magic_quotes_runtime();
var_dump($runtime);


//test里存储的是:"芝麻饼干\'小饼干"
$txt = file_get_contents('test.txt');
var_dump($txt);
//string(30) "\"芝麻饼干\\\'小饼干\" "


//读取时要加stripslashes
var_dump(stripslashes($txt));
//string(26) ""芝麻饼干\'小饼干" "

 test.txt里保存的是:"芝麻饼干\'小饼干"

 读取时候要加上stripslashes 才能正确解析。

7.4.3.2  写入文件

$txt2 = "\"芝麻饼干\'小饼干\"";
$fp2 = fopen('test2.txt','w');
fputs($fp2,$txt2);
//test2.txt的保存的是:"芝麻饼干'小饼干"
fclose($fp2);

//写入时需用addslashes
$fp3 = fopen('test3.txt','w');
fputs($fp3,addslashes($txt2));
//test3.txt的保存的是:"芝麻饼干\'小饼干"
fclose($fp3);

/**
 * 为了代码通用性
 * @param $content
 * @return mixed|string
 */
function quotes($content)
{
    if (get_magic_quotes_runtime()) {
        return addslashes($content);
    }
    return $content;
}
$fp4 = fopen('test4.txt','w');
fputs($fp4,quotes($txt2));
//test4.txt的保存的是:"芝麻饼干\'小饼干"
fclose($fp4);

 test3和test4加了addslashes之后,能正确写入。

7.4.3.3  从数据库中读取序列化的数据

懒得写代码了。反正现在有更好的方法,已经用不到此功能了。

7.5 magic_quotes_gpc/magic_quotes_sybase 、magic_quotes_runtime 区别

  • magic_quotes_gpc/magic_quotes_sybase的设定值将会影响通过Get/Post/Cookies获得的数据
  • magic_quotes_runtime的设定值将会影响从文件中读取的数据或从数据库查询得到的数据

 magic_quotes_sybase 如果打开的话,将会使用单引号对单引号进行转义而非反斜线,此选项会完全覆盖 magic_quotes_gpc。

如果同时打开两个选项的话,单引号将会被转义成 ''。而双引号、反斜线 和 NULL 字符将不会进行转义。 如何取得其值参见 ini_get()。

具体参考 https://blog.wpjam.com/article/php-magic-quotes-and-wordpress/

posted on 2024-10-16 19:38  小白兔晒黑了  阅读(10)  评论(0编辑  收藏  举报