찾다
백엔드 개발PHP 튜토리얼异常在 PHP 5.3 中的最佳实践_PHP教程

异常在 PHP 5.3 中的最佳实践

每一个新的功能添加到PHP运行时会创建一个指数随机数,通过这样的方式开发者可以使用和甚至滥用这个新特性。然而,直到一些好的和坏的使用情况陆续出现开发者们才达成了共识。当这些新案例不断浮现,我们终于可以辨别出什么是最好或最坏的做法。

异常处理在PHP中的确无论如何都不算是一个新的特征。但在本文中,我们将讨论在PHP 5.3中基于异常处理的两个新的特点。第一个是嵌套异常第二是一套SPL现在的PHP运行机制的一个核心扩展)的扩展的新的异常类型。这两个新特性,这本书里都能找到最佳实践值得各位去详细研究。

特别要注意:这些特性中的一些已经存在于低于5.3的PHP版本之中,或者至少能够在低于5.3的版本之中被实现.  而当本文提到 PHP 5.3, 并不是严责意义上的 PHP 运行时版本. 相反,它意味着代码库和项目是采用 PHP 5.3 作为最低版本的,但同时也是在新的发展阶段出现的所有最佳实践.  这个发展阶段所凸显的是特定的几个像Zend Framework, Symfony, Doctrine 以及 PEAR 这样的项目所进行的“2.0”尝试.

背景

PHP 5.2  只有一个异常类 Exception。按照 Zend Framework / PEAR 的开发标准, 这个类是你的库中所有异常类的基类。如果你创建一个名叫 MyCompany 的库,按 Zend Framework / PEAR 的标准, 库中所有的代码文件都会以 MyCompany_ 开头。要是你想给库创建自己的异常基类: MyCompany_Exception, 那就用该类继承 Exception,然后再由组件(component )继承和抛出该异常类。比如你有一个组件 MyCompany_Foo,你可以给它创建一个用在该组件内部的异常基类 MyCompany_Foo_Exception。这些异常能被捕捉 MyCompany_Foo_Exception,MyCompany_Exception 或 Exception 的代码捉到。 对于库中其他用到该组件的代码来说,这是个三层的异常(或更多,取决于 MyCompany_Foo_Exception 的子类有几层 ), 他们可以根据自己的需要处理这些异常。

在php5中,基本异常类已经支持嵌套的特性了。什么是嵌套呢?嵌套是一种能力可以去捕获特殊异常,或者捕获参照原始异常而创建的一个新的异常对象。这将会允许caller属性在更公开的类型的开销库中出现的两种异常类上得到体现,当然也会在具有原始异常行为的异常类上体现。

为什么这些特性很有用?通常,通过使用其他代码来抛出自己的类型的异常是最有效的代码。这些代码可能是使用适配器模式封装的提供一些适应性更强强的函数的第三方代码库的代码,或利用一些PHP扩展来抛出异常的简单代码。

例如,在组件 Zend_Db 中, 它使用了适配器模式来封装特定的 PHP 扩展,来创建一个数据库抽象层.  在一个适配器中, Zend_Db 封装了 PDO, 而 PDO 会抛出它自己的异常 PDOException, Zend_Db 需要捕获这些特定于 PDO 的异常,并让它们以可预期且类型已知的 Zend_Db_Exception 重新被抛出. 这样就给了开发者保证, Zend_Db 将总是抛出 Zend_Db_Exception 类型的异常(因此可以被捕获), 而他们同时也可以在需要的时候访问到最开始被抛出的 PDOException.

下面的示例展示了一个虚构的数据库适配器可能如何去实现嵌入式的异常:

<ol class="dp-c"><li class="alt"><span><span class="keyword">class</span><span> MyCompany_Database </span></span></li><li><span>{ </span></li><li class="alt"><span>    <span class="comment">/**</span> </span></li><li><span><span class="comment">     * @var PDO object setup during construction</span> </span></li><li class="alt"><span><span class="comment">     */</span><span> </span></span></li><li><span>    <span class="keyword">protected</span><span> </span><span class="vars">$_pdoResource</span><span> = null; </span></span></li><li class="alt"><span>      </span></li><li><span>    <span class="comment">/**</span> </span></li><li class="alt"><span><span class="comment">     * @throws MyCompany_Database_Exception</span> </span></li><li><span><span class="comment">     * @return int</span> </span></li><li class="alt"><span><span class="comment">     */</span><span> </span></span></li><li><span>    <span class="keyword">public</span><span> </span><span class="keyword">function</span><span> executeQuery(</span><span class="vars">$sql</span><span>) </span></span></li><li class="alt"><span>    { </span></li><li><span>        try { </span></li><li class="alt"><span>            <span class="vars">$numRows</span><span> = </span><span class="vars">$this</span><span>->_pdoResource-></span><span class="func">exec</span><span>(</span><span class="vars">$sql</span><span>); </span></span></li><li><span>        } catch (PDOException <span class="vars">$e</span><span>) { </span></span></li><li class="alt"><span>            <span class="keyword">throw</span><span> </span><span class="keyword">new</span><span> MyCompany_Database_Exception(</span><span class="string">'Query was unexecutable'</span><span>, null, </span><span class="vars">$e</span><span>); </span></span></li><li><span>        } </span></li><li class="alt"><span>        <span class="keyword">return</span><span> </span><span class="vars">$numRows</span><span>; </span></span></li><li><span>    } </span></li><li class="alt"><span>  </span></li><li><span>} </span></li></ol>

为了使用嵌入式的异常,你就得调用被捕获异常的getPrevious()方法:

<ol class="dp-c"><li class="alt"><span><span class="comment">// $sql and $connectionParameters assumed</span><span> </span></span></li><li><span>try { </span></li><li class="alt"><span>    <span class="vars">$db</span><span> = </span><span class="keyword">new</span><span> MyCompany_Database(</span><span class="string">'PDO'</span><span>, </span><span class="vars">$connectionParams</span><span>); </span></span></li><li><span>    <span class="vars">$db</span><span>->executeQuery(</span><span class="vars">$sql</span><span>); </span></span></li><li class="alt"><span>} catch (MyCompany_Database_Exception <span class="vars">$e</span><span>) { </span></span></li><li><span>    <span class="func">echo</span><span> </span><span class="string">'General Error: '</span><span> . </span><span class="vars">$e</span><span>->getMessage() . </span><span class="string">"\n"</span><span>; </span></span></li><li class="alt"><span>    <span class="vars">$pdoException</span><span> = </span><span class="vars">$e</span><span>->getPrevious(); </span></span></li><li><span>    <span class="func">echo</span><span> </span><span class="string">'PDO Specific error: '</span><span> . </span><span class="vars">$pdoException</span><span>->getMessage() . </span><span class="string">"\n"</span><span>; </span></span></li><li class="alt"><span>} </span></li></ol>

大多数最近被实现的PHP扩展都拥有OO面向对象)接口.  因此,这些API倾向于抛出异常,而不是发生错误终止。PHP中能够抛出异常的扩展,稍微列举出几个就包括有PDO, DOM, Mysqli, Phar, Soap 以及 SQLite.

新特性:新核心异常类型

在PHP 5.3开发中,我们展示了一些有趣的新异常类型。这些异常在PHP 5.2.x中已经存在,但最近还没到“重新评估”异常的最佳实践,现在他们会显得更加引人注目。他们在SPL扩展中得以应用,并在手册中列出这里)由于这些新的异常类型是PHP核心的一部分,也是SPL的一部分,它们可以被任何用PHP 5.3及以上)运行代码的人使用。虽然在编写应用程序层的代码时,看起来不那么重要,但在我们写或者使用代码库时,使用这些新异常类型变得更加重要

那么为什么新异常是普通类型?以前,开发者试图通过在异常消息提醒中放入更多的内容来赋予异常更多的含义。虽然这样做是可行的,但是它有几个缺点。一是你无法捕获基于消息的异常。这可是一个问题,如果你知道一组代码是同样的异常类型与不同的提示消息对应不同异常情况下,处理起来的难度将相当的大。例如,一个认证类,在对$auth->authenticate();;它抛出异常的相同类型的假设是异常),但不同的消息对应两个具体的故障:产生故障原因是认证服务器不能达到但是相同的异常类型却提示失败的验证消息不同。在这种情况下注意,使用异常可能不是处理认证响应最好的方式),这将需要用字符串来解析消息从而处理这两种不同的情况。

这个问题的解决办法显然是通过某种方式对异常进行编码,这样就可以在需要辨别如何对这种异常环境做出反应的时候能够更加容易的查询到。第一个反应库是使用异常基类的$code属性。另一个是通过创建可以被抛出且能描述自身行为的子类或者新的异常类。这两种方法具有相同的明显的缺点。两者都没有呈现出想这样的最好的例子。两者都不被认为是一个标准,因此每个试图复制这两种解决方案的项目都会有小的变化,这就迫使使用这需要回到文档以了解所创建的库中已经有的具体解决方案。现在通过使用SPL的新的类型方法,也称作php标准库;开发者就可以以同样的方式在他们的项目中,并且复用这些项目的新的最佳的方法已经出现。

第二个缺点是使用详细信息的做法使得理解这些异常情况对那些非英语或英语能力有限的开发者来说十分困难。这可能会使的开发者在试图理解异常信息的含义的过程十分的缓慢。许多开发者也会写关于异常的文章,因为还未出现一个统一的整合过的标准所要有同这些开发者数量相同的不同的版本来描述异常消息所描述的情况。

所以我如何去使用它们,就用这些让人无语的密密麻麻的细节描述?

现在在SPL中有总共13个新的异常类型。其中两个可被视为基类:逻辑异常和运行时异常;两种都继承php异常类。其余的方法在逻辑上可以被拆分为3组:动态调用组,逻辑组和运行时组。

动态调用组包含异常 BadFunctionCallException和BadMethodCallException,BadMethodCallException是BadFunctionCallExceptionLogicException的子类)的子类,这意味着这些异常可以被其直接类型译者注:就是异常自身的类型,大家都知道异常有很多种)、LogicException,或者Exception抓到译者注:就是catch)你应该在什么时候使用这些?通常,你应该在由一个无法处理的__call()方法产生的情况,或者回调无法不是一个有效的函数简单说,当某些东西并非is_callable())时使用。

例如:

<ol class="dp-c"><li class="alt"><span><span class="comment">// OO variant</span><span> </span></span></li><li><span><span class="keyword">class</span><span> Foo </span></span></li><li class="alt"><span>{ </span></li><li><span>    <span class="keyword">public</span><span> </span><span class="keyword">function</span><span> __call(</span><span class="vars">$method</span><span>, </span><span class="vars">$args</span><span>) </span></span></li><li class="alt"><span>    { </span></li><li><span>        <span class="keyword">switch</span><span> (</span><span class="vars">$method</span><span>) { </span></span></li><li class="alt"><span>            <span class="keyword">case</span><span> </span><span class="string">'doBar'</span><span>: </span><span class="comment">/* ... */</span><span> </span><span class="keyword">break</span><span>; </span></span></li><li><span>            <span class="keyword">default</span><span>: </span></span></li><li class="alt"><span>                <span class="keyword">throw</span><span> </span><span class="keyword">new</span><span> BadMethodCallException(</span><span class="string">'Method '</span><span> . </span><span class="vars">$method</span><span> . </span><span class="string">' is not callable by this object'</span><span>); </span></span></li><li><span>        } </span></li><li class="alt"><span>    } </span></li><li><span>  </span></li><li class="alt"><span>} </span></li><li><span>  </span></li><li class="alt"><span><span class="comment">// procedural variant</span><span> </span></span></li><li><span><span class="keyword">function</span><span> foo(</span><span class="vars">$bar</span><span>, </span><span class="vars">$baz</span><span>) { </span></span></li><li class="alt"><span>    <span class="vars">$func</span><span> = </span><span class="string">'do'</span><span> . </span><span class="vars">$baz</span><span>; </span></span></li><li><span>    <span class="keyword">if</span><span> (!</span><span class="func">is_callable</span><span>(</span><span class="vars">$func</span><span>)) { </span></span></li><li class="alt"><span>        <span class="keyword">throw</span><span> </span><span class="keyword">new</span><span> BadFunctionCallException(</span><span class="string">'Function '</span><span> . </span><span class="vars">$func</span><span> . </span><span class="string">' is not callable'</span><span>); </span></span></li><li><span>    } </span></li><li class="alt"><span>} </span></li></ol>

一个直接的例子,在__call时call_user_func()。这组异常在开发各种API动态方法的调用、函数调用时非常有用,例如这是一个可以被SOAP和XML-RPC客户端/服务端能够发送和解释的请求。

第二组是逻辑logic )组。这组由DomainException、InvalidArgumentException、LengthException、OutOfRangeException组成。这些异常也是LogicException的子类,当然也是PHP的Exception的子类。在有状态不定,或者错误的方法/函数的参数时使用这些异常。为了更好地理解这一点,我们先看看最后一组异常

最后一组是运行时runtime )组。它由OutOfBoundsException、OverflowException、RangeException、UnderflowException、UnexpectedValueExceptio组成。这些异常也是RuntimeException的子类,当然也是PHP的Exception的子类。在“运行时”runtime)的函数、方法发生异常时,这些异常运行时组)会被调用

逻辑组和运行时组如何一起工作?如果你看看对象的剖析,通常是发生的是两者之一。首先,对象将跟踪并改变状态。这意味着对象通常是不做任何事情。它可能会传递结构给它,它可能会通过setter和getter设置一些东西译者注:例如$this->foo='foo'),或者,它可能会引用其他对象。第二,当对象不跟踪或改变状态,这代表正在操作——做它该做的事。这是对象的运行时runtime)。例如,在对象的一生中,它可能被创建,设置一些东西,那么它可能会被setFoo($foo),setBar($bar)。在这些时候,任何类型的LogicException应该被提高。此外,当对象内的方法被带参数调用时,例如$object->doSomething($someVariation);在前几行检查$someVariation变量时,可能抛出一个LogicException。完成检查$someVariation后,它继续做它该做的doSomething(),这时被认为是它的“运行时”runtime),在这段代码中,可能抛出RuntimeExcpetions异常。

要理解得更好,我们来看看这个概念在代码中的运用:

<ol class="dp-c"><li class="alt"><span><span class="keyword">class</span><span> Foo </span></span></li><li><span>{ </span></li><li class="alt"><span>    <span class="keyword">protected</span><span> </span><span class="vars">$number</span><span> = 0; </span></span></li><li><span>    <span class="keyword">protected</span><span> </span><span class="vars">$bar</span><span> = null; </span></span></li><li class="alt"><span>  </span></li><li><span>    <span class="keyword">public</span><span> </span><span class="keyword">function</span><span> __construct(</span><span class="vars">$options</span><span>) </span></span></li><li class="alt"><span>    { </span></li><li><span>        <span class="comment">/** 本方法抛出LogicException异常 **/</span><span> </span></span></li><li class="alt"><span>    } </span></li><li><span>      </span></li><li class="alt"><span>    <span class="keyword">public</span><span> </span><span class="keyword">function</span><span> setNumber(</span><span class="vars">$number</span><span>) </span></span></li><li><span>    { </span></li><li class="alt"><span>        <span class="comment">/** 本方法抛出LogicException异常 **/</span><span> </span></span></li><li><span>    } </span></li><li class="alt"><span>      </span></li><li><span>    <span class="keyword">public</span><span> </span><span class="keyword">function</span><span> setBar(Bar </span><span class="vars">$bar</span><span>) </span></span></li><li class="alt"><span>    { </span></li><li><span>        <span class="comment">/** 本方法抛出LogicException异常 **/</span><span> </span></span></li><li class="alt"><span>    } </span></li><li><span>      </span></li><li class="alt"><span>    <span class="keyword">public</span><span> </span><span class="keyword">function</span><span> doSomething(</span><span class="vars">$differentNumber</span><span>) </span></span></li><li><span>    { </span></li><li class="alt"><span>        <span class="keyword">if</span><span> (</span><span class="vars">$differentNumber</span><span> != </span><span class="vars">$expectedCondition</span><span>) { </span></span></li><li><span>            <span class="comment">/** 在这里,抛出LogicException异常 **/</span><span> </span></span></li><li class="alt"><span>        } </span></li><li><span>          </span></li><li class="alt"><span>        <span class="comment">/**</span> </span></li><li><span><span class="comment">         * 在这里,本方法抛出RuntimeException异常</span> </span></li><li class="alt"><span><span class="comment">         */</span><span>  </span></span></li><li><span>    } </span></li><li class="alt"><span>  </span></li><li><span>} </span></li></ol>

现在理解了这一概念,那么,对代码库的使用者来说,这是做什么的呢?使用者可以随时确定对象的异常状态,他们可以用异常的具体的类型来捕获(catch)异常,例如InvalidArgumentException或LengthException,至少也是LogicException。通过这种级别的精度调整,和类型的多样,他们可以用LogicException捕获最小的异常,但也可以通过实际的异常类型获得更好的理解。同样的概念也适用于运行时的异常,可以抛出更多的特定类型的异常,并且不论是特定或非特定类型的异常,都可以被捕获catch)。它可以给使用者提供更详细的情况和精确度。

下面是一个关于SPL异常的表,您可能会有兴趣

类库代码中的最佳实践

PHP 5.3 带来了新的异常类型, 同时也带给我们新的最佳实践. 除了将某些特定的异常(如: InvalidArgumentException, RuntimeException)标准化外, 捕捉组件级的异常, 也很重要. 关于这方面, ZF2 wiki 和 PEAR2 wiki 上面有深入的探讨.

简而言之, 除了上面提到的各种最佳实践, 我们还应该用 Marker Interface 来创建一个组件级的异常基类. 通过创建组件级的 Marker Interface, 用在组件内部的异常既能继承 SPL 的异常类型, 也能在运行时被各种代码捕捉. 我们来看下列代码:

<ol class="dp-c"><li class="alt"><span><span class="comment">// usage of bracket syntax for brevity</span><span> </span></span></li><li><span>namespace MyCompany\Component { </span></li><li class="alt"><span>  </span></li><li><span>    <span class="keyword">interface</span><span> Exception </span></span></li><li class="alt"><span>    {} </span></li><li><span>  </span></li><li class="alt"><span>    <span class="keyword">class</span><span> UnexpectedValueException  </span></span></li><li><span>        <span class="keyword">extends</span><span> \UnexpectedValueException  </span></span></li><li class="alt"><span>        <span class="keyword">implements</span><span> Exception </span></span></li><li><span>    {} </span></li><li class="alt"><span>  </span></li><li><span>    <span class="keyword">class</span><span> Component </span></span></li><li class="alt"><span>    { </span></li><li><span>        <span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">function</span><span> doSomething() </span></span></li><li class="alt"><span>        { </span></li><li><span>            <span class="keyword">if</span><span> (</span><span class="vars">$somethingExceptionalHappens</span><span>) { </span></span></li><li class="alt"><span>                <span class="keyword">throw</span><span> </span><span class="keyword">new</span><span> UnexpectedValueException(</span><span class="string">'Something bad happened'</span><span>); </span></span></li><li><span>            } </span></li><li class="alt"><span>        } </span></li><li><span>    } </span></li><li class="alt"><span>  </span></li><li><span>} </span></li></ol>

如果调用上面代码中的 MyCompany\Component\Component::doSomething() 函数, doSomething() 抛出的异常可以当作下列异常类型捕捉: PHP 的 Exception, SPL 的 UnexpectedValueException, SPL 的 RuntimeException, 该组件的MyCompany\Component\UnexpectedValueException, 或该组件的 MyCompany\Component\Exception. 这为捕捉你的类库组件中的异常提供了极大的便利. 此外, 通过分析异常的类型, 我们也能看出某个异常的含义.  

总结

总而言之,本文旨在教大家, 创建和抛出异常的最佳标准做法, 即: 应该多关注异常的类型, 少纠结异常的错误消息。如果你有什么看法, 欢迎在这里留言, 或在 PHP 文档网页, 亦或是上面给出链接的ZF2 wiki 留言。 

 



www.bkjia.comtruehttp://www.bkjia.com/PHPjc/946150.htmlTechArticle异常在 PHP 5.3 中的最佳实践 每一个新的功能添加到PHP运行时会创建一个指数随机数,通过这样的方式开发者可以使用和甚至滥用这个新特性...
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP vs. Python : 차이점 이해PHP vs. Python : 차이점 이해Apr 11, 2025 am 12:15 AM

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP : 죽어 가거나 단순히 적응하고 있습니까?PHP : 죽어 가거나 단순히 적응하고 있습니까?Apr 11, 2025 am 12:13 AM

PHP는 죽지 않고 끊임없이 적응하고 진화합니다. 1) PHP는 1994 년부터 새로운 기술 트렌드에 적응하기 위해 여러 버전 반복을 겪었습니다. 2) 현재 전자 상거래, 컨텐츠 관리 시스템 및 기타 분야에서 널리 사용됩니다. 3) PHP8은 성능과 현대화를 개선하기 위해 JIT 컴파일러 및 기타 기능을 소개합니다. 4) Opcache를 사용하고 PSR-12 표준을 따라 성능 및 코드 품질을 최적화하십시오.

PHP의 미래 : 적응 및 혁신PHP의 미래 : 적응 및 혁신Apr 11, 2025 am 12:01 AM

PHP의 미래는 새로운 기술 트렌드에 적응하고 혁신적인 기능을 도입함으로써 달성 될 것입니다. 1) 클라우드 컴퓨팅, 컨테이너화 및 마이크로 서비스 아키텍처에 적응, Docker 및 Kubernetes 지원; 2) 성능 및 데이터 처리 효율을 향상시키기 위해 JIT 컴파일러 및 열거 유형을 도입합니다. 3) 지속적으로 성능을 최적화하고 모범 사례를 홍보합니다.

PHP의 초록 클래스 또는 인터페이스에 대한 특성과 언제 특성을 사용 하시겠습니까?PHP의 초록 클래스 또는 인터페이스에 대한 특성과 언제 특성을 사용 하시겠습니까?Apr 10, 2025 am 09:39 AM

PHP에서, 특성은 방법 재사용이 필요하지만 상속에 적합하지 않은 상황에 적합합니다. 1) 특성은 클래스에서 다중 상속의 복잡성을 피할 수 있도록 수많은 방법을 허용합니다. 2) 특성을 사용할 때는 대안과 키워드를 통해 해결할 수있는 방법 충돌에주의를 기울여야합니다. 3) 성능을 최적화하고 코드 유지 보수성을 향상시키기 위해 특성을 과도하게 사용해야하며 단일 책임을 유지해야합니다.

DIC (Dependency Injection Container) 란 무엇이며 PHP에서 사용하는 이유는 무엇입니까?DIC (Dependency Injection Container) 란 무엇이며 PHP에서 사용하는 이유는 무엇입니까?Apr 10, 2025 am 09:38 AM

의존성 주입 컨테이너 (DIC)는 PHP 프로젝트에 사용하기위한 객체 종속성을 관리하고 제공하는 도구입니다. DIC의 주요 이점에는 다음이 포함됩니다. 1. 디커플링, 구성 요소 독립적 인 코드는 유지 관리 및 테스트가 쉽습니다. 2. 유연성, 의존성을 교체 또는 수정하기 쉽습니다. 3. 테스트 가능성, 단위 테스트를 위해 모의 객체를 주입하기에 편리합니다.

SPL SplfixedArray 및 일반 PHP 어레이에 비해 성능 특성을 설명하십시오.SPL SplfixedArray 및 일반 PHP 어레이에 비해 성능 특성을 설명하십시오.Apr 10, 2025 am 09:37 AM

SplfixedArray는 PHP의 고정 크기 배열로, 고성능 및 메모리 사용이 필요한 시나리오에 적합합니다. 1) 동적 조정으로 인한 오버 헤드를 피하기 위해 생성 할 때 크기를 지정해야합니다. 2) C 언어 배열을 기반으로 메모리 및 빠른 액세스 속도를 직접 작동합니다. 3) 대규모 데이터 처리 및 메모리에 민감한 환경에 적합하지만 크기가 고정되어 있으므로주의해서 사용해야합니다.

PHP는 파일 업로드를 어떻게 단단히 처리합니까?PHP는 파일 업로드를 어떻게 단단히 처리합니까?Apr 10, 2025 am 09:37 AM

PHP는 $ \ _ 파일 변수를 통해 파일 업로드를 처리합니다. 보안을 보장하는 방법에는 다음이 포함됩니다. 1. 오류 확인 확인, 2. 파일 유형 및 크기 확인, 3 파일 덮어 쓰기 방지, 4. 파일을 영구 저장소 위치로 이동하십시오.

Null Coalescing 연산자 (??) 및 Null Coalescing 할당 연산자 (?? =)은 무엇입니까?Null Coalescing 연산자 (??) 및 Null Coalescing 할당 연산자 (?? =)은 무엇입니까?Apr 10, 2025 am 09:33 AM

JavaScript에서는 NullCoalescingOperator (??) 및 NullCoalescingAssignmentOperator (?? =)를 사용할 수 있습니다. 1. 2. ??= 변수를 오른쪽 피연산자의 값에 할당하지만 변수가 무효 또는 정의되지 않은 경우에만. 이 연산자는 코드 로직을 단순화하고 가독성과 성능을 향상시킵니다.

See all articles

핫 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 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!