php入门教程之文件操作基础

 更新时间:2016年11月25日 15:02  点击:2310
在有些场合中需要以文件的形式来对内容进行存储,通常这时候需要对文件进行一系列的操作,PHP中对于文件的操作跟其他计算机程序设计语言对文件的操作类似,对于文件的操作主要包括三个部分,以及围绕这三部分提供的辅助性函数来完成文件操作的工作。

(1)文件的创建与打开;
(2)文件的操作;
(3)文件的关闭;

在PHP中,通过一系列的函数来完成文件的操作,常用的函数及其简要说明罗列如下:

//文件打开,完成文件打开(在文件不存在时可创建文件),依赖于文件中模式的不同而具有不同的操作
resource fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] )
//$filename 打开或者要创建文件的路径及文件名,为了便于移植,使用反斜杠/为佳
//$mode 是文件打开的模式,有很多模式,比较常用的r,w,a,同样为了便于移植,建议mode中增加b(二进制)
//通常读文件为 rb ,写文件为 ab,分别表示以二进制读文件及以二进制向文件追加内容
//在文件打开操作过程中出现错误请首先检查文件所在的路径的权限设置
 

 代码如下 复制代码
//文件操作函数
 
//写操作相关函数
//把$string的内容写到文件指针$handle
int fwrite ( resource $handle , string $string [, int $length ] ) 
//函数是fwrite的别名函数
fputs()
 
//也能完成写操作,不同的是集成了fopen(),fwrite(),fclose(),使用该函数不用再打开关闭文件
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
 
//读操作相关函数
//逐行读取
string fgets ( resource $handle [, int $length ] )
//逐行读,能够过滤标记
string fgetss ( resource $handle [, int $length [, string $allowable_tags ]] )
//逐行读,能够根据定界符输出到数组
array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = ',' [, string $enclosure = '"' [, string $escape = '\' ]]]] )
//一次性读取一个文件并将文件内容发送到标准输出,包含了文件打开与文件关闭操作
int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] )
//先要打开文件,然后将文件指针所指向的文件内容发送到标准输出
int fpassthru ( resource $handle )
//把结果发送到一个数组中
array file ( string $filename [, int $flags = 0 [, resource $context ]] )
//一次读取一个字符
string fgetc ( resource $handle )
//读取任意长度字节的内容
string fread ( resource $handle , int $length )
 
//文件关闭
bool fclose ( resource $handle )
 
//文件操作中常用的函数
//检查文件或目录是否存在
bool file_exists ( string $filename )
//获取文件大小,返回文件大小的字节数
int filesize ( string $filename )
//删除文件
bool unlink ( string $filename [, resource $context ] )
//复位文件指针位置
bool rewind ( resource $handle )
//在文件指针中定位
int fseek ( resource $handle , int $offset [, int $whence = SEEK_SET ] )


函数的具体详细的说明在php.net上可以查到,下面练习一下文件的操作,练习名称为『简易日记』,需求如下:

(1)每日记录的内容以年-月-日.txt保存在数据目录下;
(2)首页写日记,并显示以往的记录;
(3)显示单页记录内容;

 

具体代码如下

首页(index.php)

 代码如下 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>简易日记--php文件操作练习</title>
    <style>
      h1 {
         font-size:24px;
         border-bottom:1px solid #000;
         line-height:40px;
      }
      .active {
         line-height:22px;
         font-size:14px;
         background:#2cf;
         padding:8px;
         text-decoration:none;
      }
      .btn {
         width:100px;
         height:40px;
      }
    </style>
  </head>
  <body>
    <h1>我的日记本</h1>
    <p><span class="active">写日记</span></p>
    <form name="writediary" method="POST" action="diaryprocessed.php">
      <p>日记主题</p>
      <input type="text" name="diarytopic" size="60" maxlength="100" />
      <p>日记内容</p>
      <textarea name="diarycontents" rows="10" cols="53"></textarea>
      <p><input  class="btn" type="submit" name="save" value="保存" /></p>
    </form>
    <hr>
    <p><span class="active">日记列表</span> </p>
    <hr>
    <?php
      $handler = opendir($_SERVER['DOCUMENT_ROOT'] . '/phpcodes/diarydatas/');
      while (($diaryname = readdir($handler)) !== false) {
        if($diaryname != "." && $diaryname != ".." ) {
          $files[] = $diaryname;
        }
      }
      closedir($handler);
      foreach($files as $value) {
        echo "<a href=viewdiary.php?id=" . substr($value,0,(strlen($value)-4)) . ">$value</a>" . " | ";
      }
    ?>
  </body>
</html>


保存处理页(diaryprocessed.php)

 代码如下 复制代码
<?php
header('Content-Type:text/html; charset=utf-8');
 
$date = gmdate('Y-m-d', time() + 3600 * 8);
 
$diarytopic = $_POST['diarytopic'];
 
$diarycontents = $_POST['diarycontents'];
 
$DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 
$output = $diarytopic . "n" . $diarycontents . "n";
 
$fp = fopen($DOCUMENT_ROOT . '/phpcodes/diarydatas/' . $date . '.txt', 'ab');
 
flock($fp,LOCK_EX);
 
if(!$fp) {
  echo "<p><strong>当前不能处理您提交的日志,请稍后再试!</strong></p>";
  echo "<a href="index.htm">返回</a>";
}
 
fwrite($fp,$output);
 
flock($fp,LOCK_UN);
 
fclose($fp);
 
echo '日记提交成功!';
echo "<a href="index.htm">返回</a>";


查看内容页(viewdiary.php)

 代码如下 复制代码

<?php
  $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>简易日记</title>
    <style>
      * { line-height: 32px; }
    </style>
  </head>
  <body>
    <a href="index.php">写日记</a>
    <hr>
    <?php
      $diaryname = $_GET['id'];
      $filepath = $DOCUMENT_ROOT . '/phpcodes/diarydatas/' . $diaryname . '.txt';
      if (file_exists($filepath)) {
        $fp = fopen($filepath, 'rb');
        echo nl2br(fread($fp,filesize($filepath)));
        fclose($fp);
      }
    ?>
  </body>
</html>

本文章来给大家介绍一篇很简单的入门教程就是php位操作了,各位有需要了解的朋友可参考。

1.&(与) 将数值转化为二进制后 都为1则为1否则为0

$a = 10; //1010
$b = 12; //1100
echo $a & $b; //得到的是8 => 1000     2.| (或) 将数值转化为二进制后 只要有一个是1则为1 否则为0

$a = 10; //1010
$b = 12; //1100
echo $a | $b; //得到的是14 => 1110     3.^ (异或)将数值转化为二进制后 相同的为0 不同的为1

$a = 10; //1010
$b = 12; //1100
echo $a ^ $b; //得到的是6 => 0110     4.~ (取非) 将数值转化为二进制后 1转为0 0转为1

$a = 10; //1010
echo ~$a; //结果是-11 => 1111111111111111111111111111111111111111111111111111111111110101     5.<< (左移) 左移几个位置就乘以几个2

$a = 10;
echo $a << 3; //结果是80     6. >> (右移) 右移几个位置除以几个2

$a = 80;
echo $a >> 3; //结果是10

在php中变量有很多种如普通的变量及全局变量(Global与$GLOBALS),本文章来给大家介绍在php中Global与$GLOBALS的用法区别。

Global,全局变量

  PHP Global变量在实际应用中会发现许多问题需要我们不断的去完善处理。我们在这篇文章中就针对PHP Global变量出现的问题给出了一些具体的解决办法。

PHP hack的使用技巧详解
代码实现PHP GTK写文本查看器
网站开发中PHP语言优缺点
如何正确实现PHP function函数扩展
PHP error_log()函数处理错误日志

1:PHP Global变量的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面,包括include或require的所有文件

 代码如下 复制代码

$a=123;
 
function aa()
{
Global $a; 
//如果不把$a定义为global变量
,函数体内是不能访问$a的
echo $a;
}
aa();

总结:

在函数体内定义的PHP Global变量,函数体外可以使用,在函数体外定义的global变量不能在函数体内使用,

 

 代码如下 复制代码
$glpbal $a; 
$a=123;  
function f() 

echo $a; //错误, 
}

再看看下面一例

 代码如下 复制代码


function f() 

global $a;  $a=123; 
}  
f(); 
echo $a;

//正确,可以使用

2:PHP Global变量问题解析:

question:我在config.inc.php中定义了一些变量($a),在别的文件中函数外部 include("config.inc.php"),函数内部需要使用这些变量$a,如果没有声明的话,echo $a是打印不出来任何东西的。因此声明global $a,但是有很多函数和很多变量,总不能不断重复的这样声明吧?有什么好的解决办法,请指点。

answer1:先在config.inc.php里定义常量:define(常量名,常量值),再在其他需要用到的地方require 'config.inc.php',然后就能在这个文件里直接使用这个常量了。

answer2:我也有个办法,就是定义数组,如$x[a],$x,那样就只要声明global $x一个了。

answer3:我试了你的这个方法,不行啊。

answer4:改你的php.ini文件。

设置PHP Global变量 为 on


,下面我们看看复杂点的:

 代码如下 复制代码

//A.php 文件

<?php
function Test_Global()
{
    include 'B.php';
    Test();
}

$a = 0 ;
Test_Global();
echo $a;
?>

//B.php 文件

<?php
function Test()
{
   global $a;//申明函数体Sum内使用的$a变量为global全局变量
   $a =1;
}
?>

为什么输出的却是0?!!

在用户自定义函数中,一个局部函数范围将被引入。任何用于函数内部的变量按缺省情况将被限制在局部函数范围内(包括include 和 require 导入的文件内的变量)!
解释:A.php文件的内Test_Global是定义好的第三方函数,该函数用include导入了B.php文件内的$a的global全局变量,所以$a被限制在Test_Global局部函数范围内,所以B.php文件内的$a的作用范围都在Test_Global内,而不是作用了整个A.php内….

解决方案:
1. 冲出局部函数

 代码如下 复制代码

//A.php 文件

<?php
function Test_Global()
{
    Test();
}
include 'B.php'; //将include 从局部Test_Global函数中移出
$a = 0 ;
Test_Global();
echo $a;
?>

//B.php 文件

<?php
function Test()
{
    global $a;
    $a =1;
}
?>


global和$GLOBALS的区别


php中global和$GLOBALS不仅仅是写法不一样以为,2者的区别还是很大的,在实际应用中需要注意!

先看下面的例子:

PHP代码

 

 代码如下 复制代码

<?php

 // 例子1

 function test_global() {

   global $var1, $var2;

   $var2 =& $var1;

 }

 function test_globals() {

   $GLOBALS['var3'] =& $GLOBALS['var1'];

 }

 $var1 = 5;

 $var2 = $var3 = 0;

 test_global();

 print $var2 .”n”;

 test_globals();

 print $var3 .”n”;

 ?> 

执行结果为:

0

5

怎么会这样呢?不应该是2个5吗?怎么会出现1个0和1个5呢?

恩,我们保留以上问题,深入分析$GLOBALS和global的原理!

我们都知道变量其实是相应物理内存在代码中的”代号”而已

引用php手册的$GLOBALS的解释:

Global 变量:$GLOBALS,注意: $GLOBALS 在 PHP 3.0.0 及以后版本中适用。

由所有已定义全局变量组成的数组。变量名就是该数组的索引。这是一个“superglobal”,或者可以描述为自动全局变量。

也就是说上面代码中的$var1和$GLOBALS['var1']是指的同一变量,而不是2个不同的变量!

下面来分析global到底做了什么?

引用php手册的global的解释:

如果在一个函数内部给一个声明为 global 的变量赋于一个引用,该引用只在函数内部可见。可以通过使用 $GLOBALS 数组避免这一点。

我们都知道php中的函数所产生的变量都是函数的私有变量,那么global关键字产生的变量也肯定逃不出这个规则,为什么这么说呢,看下面的代码:

PHP代码

 

 代码如下 复制代码

<?php

 // 例子2

 function test() {

   global $a;

   unset($a);

 }

 $a = 1;

 test();

 print $a;

 ?> 

执行结果为:

1

为什么会输出1呢?不是已经把$a给unset了吗?unset失灵了?php的bug?

都不是,其实unset起作用了,是把test函数中的$a给unset掉了,可以在函数test()中加入

print $a;

来测试!

接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化只在函数的局部产生效应,在函数外部$var2的指向物理内存地址并没有变化,还是它自己.

此时,就能理解为什么例子1执行完以后,$var2是0,而$var3是5了!

所以我们得出一个结论,在函数中global和$GLOBALS[]的区别在于:

global在函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一但改变了别名变量的指向地址,就会发生一些意料不到情况,例如例子 1.

$GLOBALS[]确确实实调用是外部的变量,函数内外会始终保持一致

可以对照 下面两个列子再加深下印象:

global:

 代码如下 复制代码

<?php

function myfunction(){

    global $bar;

    unset($bar);

}

$bar=”someting”;

myfunction();

echo $bar;

?>

输出:someting

$GLOBALS[]:

<?php

    function foo()

{

    unset($GLOBALS['bar']);

}

$bar = “something”;

foo();

echo $bar;

?>

输出:空

当按照上面的思路理解后,碰到下面的情况是不是又有些晕呢?

 代码如下 复制代码

<?php

$a = 1;

$b = 2;

function Sum()

{

   global $a, $b;

   $b = $a + $b;

}

Sum();

echo $b;

?>

输出将是 “3″。在函数中申明 了全局变量 $a 和 $b,任何变量的所有引用变量都会指向到全局变量。

怎么不是2呢,在函数外部不是不影响吗,请注意$b在函数中并没有通过引用修改,而是修改的$b指向物理内存的值,因此外部输入为3。

php中global和$GLOBALS不仅仅是写法不一样以为,2者的区别还是很大的,在实际应用中需要注意!

先看下面的例子:

PHP代码

 

 代码如下 复制代码

<?php 

 // 例子1 

 function test_global() { 

   global $var1, $var2; 

   $var2 =& $var1; 

 } 

 function test_globals() { 

   $GLOBALS['var3'] =& $GLOBALS['var1']; 

 } 

 $var1 = 5; 

 $var2 = $var3 = 0; 

 test_global(); 

 print $var2 .”n”; 

 test_globals(); 

 print $var3 .”n”; 

 ?>  

 

执行结果为:

0

5

怎么会这样呢?不应该是2个5吗?怎么会出现1个0和1个5呢?

恩,我们保留以上问题,深入分析$GLOBALS和global的原理!

我们都知道变量其实是相应物理内存在代码中的“代号“而已

引用php手册的$GLOBALS的解释:

Global 变量:$GLOBALS,注意: $GLOBALS 在 PHP 3.0.0 及以后版本中适用。

由所有已定义全局变量组成的数组。变量名就是该数组的索引。这是一个“superglobal”,或者可以描述为自动全局变量。

也就是说上面代码中的$var1和$GLOBALS['var1']是指的同一变量,而不是2个不同的变量!

 

下面来分析global到底做了什么?

引用php手册的global的解释:

如果在一个函数内部给一个声明为 global 的变量赋于一个引用,该引用只在函数内部可见。可以通过使用 $GLOBALS 数组避免这一点。

我们都知道php中的函数所产生的变量都是函数的私有变量,那么global关键字产生的变量也肯定逃不出这个规则,为什么这么说呢,看下面的代码:

PHP代码

 代码如下 复制代码

 <?php 

 // 例子2 

 function test() { 

   global $a; 

   unset($a); 

 } 

  

 $a = 1; 

 test(); 

 print $a; 

 ?>  

 

执行结果为:

1

为什么会输出1呢?不是已经把$a给unset了吗?unset失灵了?php的bug?

都不是,其实unset起作用了,是把test函数中的$a给unset掉了,可以在函数test()中加入

print $a;

来测试!

 

接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化只在函数的局部产生效应,在函数外部$var2的指向物理内存地址并没有变化,还是它自己.

此时,就能理解为什么例子1执行完以后,$var2是0,而$var3是5了!

 

所以我们得出一个结论,在函数中global和$GLOBALS[]的区别在于:

global在函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一但改变了别名变量的指向地址,就会发生一些意料不到情况,例如例子 1.

 

$GLOBALS[]确确实实调用是外部的变量,函数内外会始终保持一致

可以对照 下面两个列子再加深下印象:

global:

 代码如下 复制代码

<?php

function myfunction(){

    global $bar;

    unset($bar);

}

$bar=”someting”;

myfunction();

echo $bar;

?>

输出:someting

 

 代码如下 复制代码

$GLOBALS[]:

<?php

    function foo()

{

    unset($GLOBALS['bar']);

}

$bar = “something”;

foo();

echo $bar;

?>

输出:空

 

当按照上面的思路理解后,碰到下面的情况是不是又有些晕呢?

 代码如下 复制代码

<?php

$a = 1;

$b = 2;

function Sum()

{

   global $a, $b;

   $b = $a + $b;

}

Sum();

echo $b;

?>

输出将是 “3″。在函数中申明 了全局变量 $a 和 $b,任何变量的所有引用变量都会指向到全局变量。

怎么不是2呢,在函数外部不是不影响吗,请注意$b在函数中并没有通过引用修改,而是修改的$b指向物理内存的值,因此外部输入为3。

变量是php中非常常用的一个东西,所有的操作都要经过变量来传递,下面我来给各位同学介绍在php中变量的一些常用用法与关于php变量基础知识。

具体方法

PHP 变量

PHP变量用于存储字符、数字、数组甚至对象内容等,以便在我们需要的地方使用。

定义一个变量的语法:

$变量名 = 值;

使用变量的例子:

 

 代码如下 复制代码

 <?php 

 $var_char = "你好!"; 

 echo $var_char; 

 ?>

执行这段代码输出的结果是:


1 你好!
从这个例子可以看出,变量名以 $ 开始,标明这是一个变量。变量名以字母(a-z、A-Z)或者下划线 _ 开始,后面可以跟任意字母或数字以及下划线,但不能是空格。

如下这些变量名是有效的:


 $var_char

 $varChar

 $_varChar

 $var_char5

提示

关于变量命名,我们建议变量名以标明其实际语意的组合为佳,如 $my_name 或 $myName 格式。


全局变量global


全局变量便是其中之一,当然这个观点颇具争议,有许多人还是建议禁用全局变量,使用不当对造成程序的可读性很差!结构混乱,调试更是一头雾水,但是不可否认他的便捷,这便是php为什么会用全局变量global原因吧!…

今天就遇到了php 全局变量不起作用的问题.

先上一段简单的代码:

 代码如下 复制代码

<?php
$a = 0 ;
function Test()
{
    $a =1;
}
Test();
echo $a;
?>

上面的代码中输出是0,那是因为函数体Test内$a变量被缺省设置为局部变量,$a的作用域就是在Test内.修改代码如下

 代码如下 复制代码

<?php
$a = 0 ;
function Test()
{
   global $a;//申明函数体Test内使用的$a变量为global全局变量
   $a =1;
}
Test();
echo $a;
?>

申明函数体Test内使用的$a变量为global全局变量后,使得$a的作用全局,所以输出为1.
上面的实例只是基本的global全局变量知识,下面我们看看复杂点的:

 代码如下 复制代码

//A.php 文件

<?php
function Test_Global()
{
    include 'B.php';
    Test();
}

$a = 0 ;
Test_Global();
echo $a;
?>

//B.php 文件

<?php
function Test()
{
   global $a;//申明函数体Sum内使用的$a变量为global全局变量
   $a =1;
}
?>


为什么输出的却是0?!!

在用户自定义函数中,一个局部函数范围将被引入。任何用于函数内部的变量按缺省情况将被限制在局部函数范围内(包括include 和 require 导入的文件内的变量)!
解释:A.php文件的内Test_Global是定义好的第三方函数,该函数用include导入了B.php文件内的$a的global全局变量,所以$a被限制在Test_Global局部函数范围内,所以B.php文件内的$a的作用范围都在Test_Global内,而不是作用了整个A.php内….

解决方案:

1. 冲出局部函数//A.php 文件

 代码如下 复制代码

<?php
function Test_Global()
{
    Test();
}
include 'B.php'; //将include 从局部Test_Global函数中移出
$a = 0 ;
Test_Global();
echo $a;
?>

//B.php 文件

<?php
function Test()
{
    global $a;
    $a =1;
}
?>


2.优秀的访问器

 代码如下 复制代码

//A.php 文件
<?php
include 'B.php';
$a =0;
Set_Global($a);
echo $a;
?>

//B.php 文件

<?php
function Set_Global(&$var)
{
    $var=1;
}
?>


 

php变量 引用函数 static变量

“无论怎样声明变量(按值或按引用),总之在PHP脚本的任何位置都可以声明变量。但是,声明的位置会大大影响访问变量的范围。这个可访问的范围称为作用域(scope)” –PHP与MySQL程序设计
在了解php变量之前,我们先看看段式内存管理架构的内存段的划分。通常操作系统会将物理内存划分为以下几个逻辑段。


Text-Segment,这个段最大的特点就是只读。一般存放可执行代码,也有可能常量也存放在这里,比如字符串常量
BSS-Segment,这里存放了那些没有初始化的变量。某种意义来讲,没有初始化的变量都是垃圾,不可用
Data-Segment,这里存放了全局变量和静态变量,直到脚本运行结束,操作系统才会回收这里的内存空间,变量亦会被销毁。
Stack-Heap Segment 函数参数与本地变量(也称局部变量)存放在堆中(stack),还有返回值等等。用完了,操作系统就会回收这部分内存空间。对于C程序员而言,可以自行从栈中(heap)申请内存空间,用完了,也需要自己手动释放。
作为PHP程序言而言,我们关心的是全局变量、静态变量、局部变量、函数参数以及函数返回值。局部变量和函数参数基本上一样,在初始化的时候分配内存空间,退出函数后操作系统会回收内存空间。而全局变量与静态变量要直php脚本运行结束后,内存空间才会被释放。与全局变量不同的时,所有静态变量在程序执行之前就初始化并且分配了内存空间。

注:
1.函数外部声明静态变量意义不大,函数内部声明静态变量受限于作用域,函数外部不能修改函数内部静态变量。
2.引用变量,也是变量,只不过它的值是变量的内存地址。

php保留字 global和static

 代码如下 复制代码
<?php
$i = $j = 8;
function global_var() {
   global $j, $b;
   $c = $j = $b = $i = 4;
}
global_var();
echo "i:$i, j:$j b:$b c:$c n"; //i:8, j:4 b:4 c:
?>

函数外和内都有变量$i,但是他们二个是完全不同的变量。函数外的$i是全局变量,该内存空间直到脚本运行结束后才会被释放。函数内的$i是局部变量,程序流经过函数的时候,初始化,退出函数的时候,内存被系统回收,再次调用函数,则再次分配内存空间和回收内存空间。二次分配的内存空间有可能是同一内存地址,也有可能不能同一内存地址。
与$i不同的是$j,通过关键字global将局部变量”转为”全局变量。当调用函数global_var()的时候,并不会重新给$j分配内存空间。同样的,可以在函数外打印$b,却不能打印$c是因为$b是全局变量,不会被销毁。而$c则不能打印,$c已经不存在了,在退出函数就给销毁了。

 代码如下 复制代码
<?php
$a = 2;
static $b = 2;
static $c = 3;
function global_var() {
    static $i, $c;
    global $j, $a;
    $c = $a = $b = $i = $j = 4;
}
global_var();
echo "a:$a b:$b c:$c i:$i j:$j"; //a:4 b:2 c:3 i: j:4
?>

首先,我们看函数外的$b和$c,即是全局变量又是static变量。这里static修饰没有太大的意义,因为他们都存放在数据段(data-segment),直到脚本运行完了之后才会被回收。然后,我们再看函数里面的$i和$c,函数调用后,$i和$c其实都没有被回收,但是$i输出是NULL和$c输出是3,这是因为他们的作用域是函数内部,不是函数外部,也就是说$i和$c在函数外是不可见的。函数内static变量的意义就在于此:仅函数内部可见且不会被销毁。也就是说,保证函退出函数,变量也不会被回收,但又不会被其它函数修改。(注:函数外和函数内的$c是二个不同的变量)

 代码如下 复制代码
<?php
function global_var() {
   static $i;
   ++$j;
   ++$i;
   echo "j:$j i:$i n";
}
global_var(); //j:1 i:1 
global_var();  //j:1 i:2
global_var();  //j:1 i:3
?>

上例中,变量$j一直都是1,而$i每调用一次就累加1。这是因为,局部变量存放在堆段,每次退出函数时都会被回收。而$i存放在存放在数据段(data-segment),直到程序执行完毕才会被回收。我们平常说的static变量,如果没有特别指明,都说的是函数内部的static变量。

引用函数与static变量
既然static变量要直到脚本执行结束,才会被销毁。那么,有没有办法访问该变量的值呢?我们来看看下面的示例:

 代码如下 复制代码
<?php
get_local_static_var();
$ptr = &get_local_static_var();
get_local_static_var();
++$ptr;
get_local_static_var();
what_i($ptr);
get_local_static_var();  //??
what_p($ptr);
get_local_static_var();  //??
 
function &get_local_static_var() {
    static $i;
    ++$i;
    echo "i:$i n";
    return $i;
}
 
function what_i($ptr) {
   $i = &get_local_static_var();
   ++$i;
   ++$ptr;
}
 
function what_p(&$ptr) {
   $i = &get_local_static_var();
   ++$i;
   ++$ptr;
}
?>

二个凝问号处,分别输出是8和12。这就说明了只要变量没有被销毁,还是可以被访问。我们可以通过引用函数将static变量的地址返回其它函数。其它函数则可通过static变量的地址访问并且修改它的值。
上例第一处??,为什么是8,而不是9。这是因为what_i($ptr)函数,要求参数是按值传递,即此处的$ptr实参值是5,且参数$ptr和全局变量$ptr是二个不同的变量。第二处??的值是12,为什么不是11的道理亦是如此。what_p(&$ptr)函数,要求参数是按引用传递,即此处的$ptr是指向static变量$i的地址,需要注意的是参数$ptr和全局变量$ptr也是二个不同的变量,只不过他们都指向同一个地方。

drupal应用赏析
drupal定义了一个drupal_static函数,其它函数的static变量都存放在一个数组中,然后对drupal应用到的所有static进行统一管理,比如赋值,重置,删除等。我觉得,这是一个好办法。

 代码如下 复制代码

<?
function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
  static $data = array(), $default = array();
  if (!isset($name)) {
    foreach ($default as $name => $value) {
      $data[$name] = $value;
    }
    return $data;
  }
  if ($reset) {
    if (array_key_exists($name, $default)) {
      $data[$name] = $default[$name];
    }
    else {
      return $data;
    }
  }
  elseif (!array_key_exists($name, $data)) {
    $default[$name] = $data[$name] = $default_value;
  }
  return $data[$name];
}
 
function ip_address() {
  $ip_address = &drupal_static(__FUNCTION__);
 
  if (!isset($ip_address)) {
    $ip_address = $_SERVER['REMOTE_ADDR'];
 
    if (variable_get('reverse_proxy', 0)) {
      if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
        $reverse_proxy_addresses = variable_get('reverse_proxy_addresses', array());
        if (!empty($reverse_proxy_addresses) &&
     in_array($ip_address, $reverse_proxy_addresses, TRUE)
    ) {
          $ip_address_parts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
          $ip_address = trim(array_pop($ip_address_parts));
        }
      }
      if (array_key_exists('HTTP_X_CLUSTER_CLIENT_IP', $_SERVER)) {
        $ip_address = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
      }
    }
  }
 
  return $ip_address;
}
 
ip_address();
//在drupal中很多这样的应用方式,将其它函数的static变量都存放到一个地方,即drupal_static的data中,然后再统一管理,比如重置等等。
?>

常量在php中是一个非常重新的数据类型了,下面我来给初学者详细介绍PHP常量一些用法,有需要了解的同学可进入参考。

PHP 常量
define() 函数用于定义常量。一个常量一旦被定义,就不能再改变或者取消定义。

定义常量的例子:

 代码如下 复制代码

<?php
define("CONSTANT", "你好!");
echo CONSTANT;
?>

常量名和其它任何 PHP 标签遵循同样的命名规则。合法的常量名以字母或下划线开始,后面跟着任何字母,数字或下划线。

常量默认为大小写敏感,按照惯例常量标识符总是大写的,在脚本执行期间该值不能改变。

定义常量和定义变量的区别:

1.常量前面没有美元符号($)
2.常量只能用 define() 函数定义,而不能通过赋值语句
3.常量可以不用理会变量范围的规则而在任何地方定义和访问
4.常量一旦定义就不能被重新定义或者取消定义
5.常量的值只能是标量
PHP内置了大量预定义常量,具体的可以在网上搜PHP手册里面有具体的内容。


判断一个常量是否已经定义


如何判断一个php常量是否已经定义过了,突然之间还有点迷茫,晕,特意查了下手册,备案本次总结结果如下:

(1)判断常量是否存在

 代码如下 复制代码

 if(defined('MYCONSTANT')){ 

    echo MYCONSTANT;  

 }

(2)判断变量是否定义

 代码如下 复制代码

if(isset($myvar)){ 

    echo "存在变量$myvar.";  
3 }


(3)判断函数是否存在

 代码如下 复制代码

if(function_exists('imap_open')){
 echo "存在函数imag_open";
}else{
 echo "函数imag_open不存在";
}


常量和变量相比,不同点:

1:常量是全局有效的, 因此在页面内,函数内,类内部甚至数组内部都可以直接引用.
 

 代码如下 复制代码
   $a=66;
    function t(){ echo $a; }
    t();//此时不能打印出来99,因为函数作用域影响,如果要打印出99,可以改为:
    define(“A”,66);
    function t(){ echo A; }
    t();

2:常量一旦定义,就不可以重新定义,不可以清除.也不可以修改;

常量也可以动态的哦

 

 代码如下 复制代码

define("A","常量介绍");
  define("B","常量动态调用");
  $c=$_get['c'];//此处直接把b的值,并不会再b的值当成常量名再次解析
  echo constant($c);// constant(常量名)  ---> 返回常量的值


 

面向对象之const常量修饰符

中常用的常量修饰符const。

我们知道,在PHP中定义常量是通过define()函数来完成的,但在类中定义常量不能使用define(),而需要使用const修饰符。类中的常量使用const定义后,其访问方式和静态成员类似,都是通过类名或在成员方法中使用self访问,但在PHP 5.3.0之后也可以使用对象来访问。被const定义的常量不能重新赋值,如果在程序中试图改变它的值将会出现错误

 代码如下 复制代码


<?php 

    class MyClass { 

          const CONSTANT = 'CONSTANT value' ; //使用const声明一个常量,并直接赋上初使值 

            function showConstant() {                

                   echo  self ::CONSTANT ."<br>" ;//使用self访问常量,注意常量前不要加“$” 

             } 

      } 
      echo MyClass:: CONSTANT . "<br>" ; //在类外部使用类名称访问常量,也不要加”$” 
      $class = new MyClass();                      

     $class->showConstant();                       

      echo $class ::CONSTANT;  // PHP 5.3.0之后 

 ?>

关注细节:使用const定义的常量名称前不需要使用“$“符号,且常量名称通常都是大写的。


试图为const定义的常量赋值,将会出现错误。

 代码如下 复制代码

<?php 

     class MyClass { 

          const CONSTANT = 'CONSTANT value' ;   

             function setCONSTANT(){ 

               self ::CONSTANT  = 'news CONSTANT' ;//程序运行结果将会出错。 

      } 

                                                                                                                                                                                         

      } 
     echo MyClass:: CONSTANT ;           

                                                                                                                                                                            

?>


CONSTANTS and PHP Class Definitions

Using "define('MY_VAR', 'default value')" INSIDE a class definition does not work. You have to use the PHP keyword 'const' and initialize it with a scalar value -- boolean, int, float, or string (no array or other object types) -- right away.

不能在类里面使用"define('MY_VAR', 'default value')"来定义常量,你必须使用PHP的关键字 'const'去初始化一个标量--boolean, int, float, or string (除了数组和其他对象类型)、

 代码如下 复制代码

<?php

define('MIN_VALUE', '0.0');   // RIGHT - Works OUTSIDE of a class definition.
define('MAX_VALUE', '1.0');   // RIGHT - Works OUTSIDE of a class definition.

//const MIN_VALUE = 0.0;         WRONG - Works INSIDE of a class definition.
//const MAX_VALUE = 1.0;         WRONG - Works INSIDE of a class definition.

class Constants
{
  //define('MIN_VALUE', '0.0');  WRONG - Works OUTSIDE of a class definition.
  //define('MAX_VALUE', '1.0');  WRONG - Works OUTSIDE of a class definition.

  const MIN_VALUE = 0.0;      // RIGHT - Works INSIDE of a class definition.
  const MAX_VALUE = 1.0;      // RIGHT - Works INSIDE of a class definition.

  public static function getMinValue()
  {
    return self::MIN_VALUE;
  }

  public static function getMaxValue()
  {
    return self::MAX_VALUE;
  }
}

?>

#Example 1:
You can access these constants DIRECTLY like so:
 * type the class name exactly.
 * type two (2) colons.
 * type the const name exactly.

#Example 2:
Because our class definition provides two (2) static functions, you can also access them like so:
 * type the class name exactly.
 * type two (2) colons.
 * type the function name exactly (with the parentheses).

 代码如下 复制代码

<?php

#Example 1:
$min = Constants::MIN_VALUE;
$max = Constants::MAX_VALUE;

#Example 2:
$min = Constants::getMinValue();
$max = Constants::getMaxValue();

?>

 

Once class constants are declared AND initialized, they cannot be set to different values -- that is why there are no setMinValue() and setMaxValue() functions in the class definition -- which means they are READ-ONLY and STATIC (shared by all instances of the class).

当类常量被声明和初始化后,他们就不能被设置成其他值--这就是为什么他们在类定义时没有setMinValue()和setMaxValue()这两个方法--这说明他们都是只读而且是静态的(被所有该类的对象共享)。

[!--infotagslink--]

相关文章

  • Lua语言新手简单入门教程

    这篇文章主要给大家介绍的是关于Lua语言新手入门的简单教程,文中通过示例代码一步步介绍的非常详细,对各位新手们的入门提供了一个很方便的教程,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。...2020-06-30
  • nodejs文件操作模块FS(File System)常用函数简明总结

    件系统操作相关的函数挺多的。首先可以分为两大类。一类是异步+回调的。 一类是同步的。在这里只对异步的进行整理,同步的只需要在函数名称后面加上Sync即可1. 首先是一类最常规的读写函数,函数名称和形式,应该是起源于C...2014-06-07
  • PHP安装threads多线程扩展基础教程

    一、下载pthreads扩展下载地址:http://windows.php.net/downloads/pecl/releases/pthreads二、判断PHP是ts还是nts版通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabled,一般来说...2015-11-24
  • 编程新手必须掌握的:session与cookie的区别

    session和cookie是网站浏览中较为常见的两个概念,也是比较难以辨析的两个概念,但它们在点击流及基于用户浏览行为的网站分析中却相当关键。基于网上一些文章和资料的参阅,及作者个人的应用体会,对这两个概念做一个简单的阐述...2013-09-11
  • C#线程入门教程之单线程介绍

    这篇文章主要介绍了C#线程入门教程之单线程介绍,本文讲解了什么是进程、什么是线程、什么是多线程等内容,并给出了一个单线程代码示例,需要的朋友可以参考下...2020-06-25
  • CocosCreator入门教程之用TS制作第一个游戏

    这篇文章主要介绍了CocosCreator入门教程之用TS制作第一个游戏,对TypeScript感兴趣的同学,一定要看一下...2021-04-16
  • Flex网页布局基础入门及实例教程

    Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。本教程我们来学习一下Flex布局的基本语法知识及运用实例。 网页布局(layout)是CSS的一...2016-09-14
  • 从零开始的html教程(7):html表单基础之一

    一聚教程网 从零开始的html教程(7),html表单的基础,零基础也能轻松学会html,希望大家喜欢 一、html的表单 表单负责网页中用户输入数据采集的功能,利用<form>标签来定...2016-12-31
  • python基础之局部变量和全局变量

    这篇文章主要介绍了python局部变量和全局变量,实例分析了Python中返回一个返回值与多个返回值的方法,需要的朋友可以参考下...2021-10-22
  • 一文秒懂JavaScript DOM操作基础

    通过这篇文章帮助大家快速学习JavaScript DOM操作基础的相关知识,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧...2021-04-30
  • C# 对文件与文件夹的操作包括删除、移动与复制

    在.Net中,对文件(File)和文件夹(Folder)的操作可以使用File类和Directory类,也可以使用FileInfo类和DirectoryInfo类,本文将详细介绍,需要的朋友可以参考...2020-06-25
  • php fopen 函数 读写文件操作

    php fopen 函数 读写文件操作 function getFile($url) { if($f=fopen("$url","r")) { while(!feof($f)) { $s.=fgets($f...2016-11-25
  • php入门教程(类实例教程)

    这里主要讲到关于在php教程类的调用,申请明,使用以前各种类的实例方法与操作过程,让你清楚的知道php类的construct destruct clone call wake sleep用法。 简单购物车...2016-11-25
  • Painter基础教程之图像水管分享

    今天小编在这里就来给Painter的这一款软件的使用者们来说下基础教程之图像水管,各位想知道的使用者们,那么下面就快来跟着小编一起看看吧。 给各位Painter软件的使...2016-09-14
  • php入门教程,?号表达式

    下面举一个很简单的?表达式的实现吧,其实它就是简单的if else哦。 <? $a = 5; //定义变数a=5 $b = 3; //定义变数b=5 $c = ($a==$b) ? ("yes") : ("no"); //如果...2016-11-25
  • python开发App基础操作API使用示例过程

    这篇文章主要为大家介绍了python开发App基础操作API使用的示例过程有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...2021-10-30
  • 一篇文章带你了解C语言:入门基础(2)

    这篇文章主要介绍了C语言入门之基础知识详解,文中有非常详细的C语言使用教程及相关基础知识,对正在学习c语言的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-08-04
  • 一看就懂的ReactJs基础入门教程-精华版

    现在最热门的前端框架有AngularJS、React、Bootstrap等。自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略ReactJs的风采吧~~ 文章有点长,耐心读完,你会有很大收获哦...2021-04-05
  • 深入解析Java反射之基础篇

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,这篇文章主要给大家介绍了关于Java反射之基础篇的相关资料,需要的朋友可以参考下...2021-11-18
  • perl 文件操作总结

    perl 文件操作总结,需要的朋友可以参考下...2020-06-29