찾다

Modern PHP读书笔记一

关于PHP,大家的误解比较多,但其实现代PHP是一门无论开发效率还是执行效率都相当高的编程语言。关于现代PHP的各方面特性,大家可以参考<modern php></modern>作者之前写的 PHP the right way,中文翻译:PHP之道。同时,作者也是比较流行的PHP框架 – Slim 的开发者。所以这本书非常值得已读,甚至你只需要懂一些OOP的概念即可,并不需要你懂PHP开发。

  • Part 1 Language Feature
    • Features
      • Namespaces
        • Helpful Tips
      • Code to an interface
      • Trait
      • Generators
      • Closures
      • Zend Opcache
      • Built-in HTTP server
  • Part 2 Good Pratices
    • Standards
      • PHP-FIG
      • PSR
        • PSR-1 Basic Coding standard
        • PSR-2 Strict Code Style
        • PSR-3 Logger Interface
        • PSR-4 Autoloaders
    • Components
      • Components
      • Composer
      • Semantic Versioning
      • Create PHP Components

Part 1. Language Feature

Features

Namespaces

PHP命名空间使用 “\” 字符来分割sumnamespaces。与操作系统的物理文件系统不同,PHP命名空间是一个抽象概念,不必跟文件目录一一对应。大多数PHP Components都是根据PSR-4 autoloader standard来组织subnamespaces与文件目录的映射关系的。

从技术上来说,namespaces仅仅是一个PHP语言的符号,PHP解释器使用这个符号来作为一组classes/interfaces/functions/constants集合的前缀,仅此而已。

Namespaces are important because they let us create sandboxed code that works alongside other developer's code. This is the cornerstone concept of the modern PHP component ecosystem.

Helpful Tips

1. Multiple imports
bad:

<code class="language-php?linenums hljs tex"><?phpuse Symfony<span class="hljs-command">\Component</span><span class="hljs-command">\HttpFoundation</span><span class="hljs-command">\Request</span>,        Symfony<span class="hljs-command">\Component</span><span class="hljs-command">\HttpFoundation</span><span class="hljs-command">\Response</span>,        Symfony<span class="hljs-command">\Component</span><span class="hljs-command">\HttpFoundation</span><span class="hljs-command">\Cookie</span>;</code>

good:

<code class="language-php?linenums hljs tex"><?phpuse Symfony<span class="hljs-command">\Component</span><span class="hljs-command">\HttpFoundation</span><span class="hljs-command">\Request</span>; use Symfony<span class="hljs-command">\Component</span><span class="hljs-command">\HttpFoundation</span><span class="hljs-command">\Response</span>; use Symfony<span class="hljs-command">\Component</span><span class="hljs-command">\HttpFoundation</span><span class="hljs-command">\Cookie</span>;</code>

2. one class per file

3.Global namespace
如果我们引用一个没有命名空间的class/interface/function/constant,PHP会首先假设这个class/interface/function/constant在当前的命名空间中。如果在当前命名空间中没有找到,PHP才会开始resolve。而对于那些没有没有命名空间的代码,PHP认为他们存在于global namespace。

PSR-4

Code to an interface

An interface is a contract between tow PHP objects that lets one object depend not on what another object is but, instead, on what another can do.

Trait

A trait is a partial class implementation(i.e., constants, properties, and methods) that can be mixed into one or more existing PHP classes. Traits work double duty: they say what a class can do (like an interface), and they provide a modular implementation (like class).

相对Android开发,我最喜欢的iOS中一个特性就是category,PHP的trait就是有点类似于category,不过还是不太一样的:
1. OC只能针对特定的类进行扩展,而PHP的trait可以将代码单元注入到任意的不相关的类中;
2. 同时OC中的category并不能直接实现属性的扩展,而PHP的trait则能实现常量,属性,以及方法;
3. PHP的trait跟OC的category根本上来说用途是不一样的,OC是对现存类直接扩展,不需要继承实现类。而PHP的trait需要在类的定义中使用 use 来明确。

跟class和interface的定义一样,on trait per file

Generators

Generators are easy to create because they are just PHP functions that use the yield keyword one or more times. Unlike regular PHP functions, generators never return a value. They only yield values.

这个概念并不陌生,Python包括Swift都有这个特性,可以用在对大量数据的迭代中,动态去获取数据,而不是一次性生成,避免内存的浪费。

在每次迭代的过程中,PHP都会让Generator实例计算和提供下一个迭代值。在这个过程中,当generator执行到yield value的时候,generator会暂停它的内部状态的执行。只有generator被要求提供下一个迭代值的时候,它才会继续它的内部状态的执行。generator就这样反复pasuing 和 resuming,直到到达generator的函数定义的尾部或empty的时候,generator才会结束执行。

Generators are a tradeoff between versatility and simplicity. Generators are forward-only iterators.

Closures

A closure is a function that encapsulates its surrounding state at the time it is created. The encapsulated state exists inside the closure even when the closure lives after it original environment ceases to exist.

这里的闭包是指Closure和Anonymous functions。上面是作者对于闭包的解释,感觉非常准确,比我看到的大多数解释都要简单清晰。闭包在日常业务开发中非常有用,可以非常方便替换我们经常需要用到的delegate设计模式,不需要再去定义一个interface,然后再实现这个interface,再把对应的对象指针传递过去。而是通过Closure,只需要简简单单传递一段代码即可,这个极大简化了日常业务开发。所以目前iOS开发中,大家通常都会使用block来代替delegate设计模式。

PHP Closure or Anonymous function 跟PHP function的定义语法是一样的,但是实际上 Closure 的背后是Closure class的实例,所以Closure被认为是first-class value types。

Attach State : PHP的Closure不会automatically enclose application state,不像JavaScript/OC那样会capture作用域之外的变量。而是,you must manually attach state to a PHP closure with the closure object's bindTo() method or the use keyword.

需要注意的是,PHP closures是objects。而我们之所以能让一个closure 实例变量进行调用,是因为这个对象实现 __invoke() magic method,当我们在closure实例变量后面跟着一个 () 的时候,closure实例变量就会寻找并且调用__invoke() 方法,例如 $closure("Jason")

同样,由于PHP closure是objects。所以,在closure内部我们也可以通过 $this 访问closure的各种内部状态,但是这个状态是非常boring。同时,closure的bindTo()方法可以有一些非常有趣的特殊用法,This method lets us bind a Closure object's internal state to a different object. The bindTo() method accepts an important second argument that specifies the PHP class of the object to which the closure is bound.This lets the closure access protected and private member variables of the object to which it is bound.。这个用法有点类似JavaScript的bind方法,可以改变Closure object的 $this 指针指向。

bindTo()这个有趣的用法,经常各种PHP框架的路由所采用,例如:

<code class="language-php?linenums hljs xml"><span class="php"><span class="hljs-preprocessor"><?</span> php<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span>{</span>    <span class="hljs-keyword">protected</span> <span class="hljs-variable">$routes</span> = <span class="hljs-keyword">array</span>();    <span class="hljs-keyword">protected</span> <span class="hljs-variable">$responseStatus</span> = <span class="hljs-string">'200 OK'</span>;    <span class="hljs-keyword">protected</span> <span class="hljs-variable">$responseContentType</span> =<span class="hljs-string">'text/html'</span>;    <span class="hljs-keyword">protected</span> <span class="hljs-variable">$responseBody</span> = <span class="hljs-string">'Hello world'</span>;    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addRoute</span><span class="hljs-params">(<span class="hljs-variable">$routePath</span>, <span class="hljs-variable">$routeCallback</span>)</span>    {</span>        <span class="hljs-comment">// 将Closure bind到App类上</span>        <span class="hljs-variable">$this</span>->routes[<span class="hljs-variable">$routePath</span>] = <span class="hljs-variable">$routeCallback</span>->bindTo(<span class="hljs-variable">$this</span>, <span class="hljs-keyword">__CLASS__</span>);    }    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatch</span><span class="hljs-params">(<span class="hljs-variable">$currentPath</span>)</span>    {</span>        <span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$this</span>->routes <span class="hljs-keyword">as</span> <span class="hljs-variable">$routePath</span> => <span class="hljs-variable">$callback</span>) {            <span class="hljs-keyword">if</span> (<span class="hljs-variable">$routePath</span> === <span class="hljs-variable">$currentPath</span>) {                <span class="hljs-variable">$callback</span>();            }        }        <span class="hljs-comment">// 这里返回的state是在callback内修改过的</span>        header(<span class="hljs-string">'HTTP/1.1 '</span>.<span class="hljs-variable">$this</span>.responseStatus);        header(<span class="hljs-string">'Content-type: '</span>.<span class="hljs-variable">$this</span>.responseContentType);        header(<span class="hljs-string">'Content-length: '</span>.mb_strlen(<span class="hljs-variable">$this</span>->responseBody));        <span class="hljs-keyword">echo</span> <span class="hljs-variable">$this</span>->responseBody;    }}<span class="hljs-comment">// 添加注册一个路由</span><span class="hljs-preprocessor"><?php</span><span class="hljs-variable">$app</span> = <span class="hljs-keyword">new</span> App();<span class="hljs-variable">$app</span>->addRoute(<span class="hljs-string">'/users/josh'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>    <span class="hljs-comment">// 因为这个route是bindTo到App class上的,所以这里直接访问$this修改 App 的内部state</span>    <span class="hljs-variable">$this</span>->responseContentType = <span class="hljs-string">'application/json;charset=utf8'</span>;    <span class="hljs-variable">$this</span>->responseBody = <span class="hljs-string">'{"name": "Josh"}'</span>;});<span class="hljs-variable">$app</span>->dispatch(<span class="hljs-string">'/users/josh'</span>);</span></code>

Zend Opcache

从PHP 5.5.0开始,PHP引入了内置的bytecode cache支持,叫做 Zend OPcache。PHP解释器在执行PHP脚本的时候,会首先把PHP代码编译为Zend Opcodes (machine-code instructions),然后才会执行bytecode。在所有请求中,PHP解释器都需要这样处理所有的PHP文件,read/parse/compiles,然而我们可以通过把PHP文件预编为PHP bytecode来省略这个开销,这就是Zend OPcache

Zend OPcache的使用非常简单,在我们配置之后,它就会在内存中自动缓存precompiled PHP bytecode,在可用的情况就会直接执行这个PHP bytecode,而不需要再去编译PHP代码。

具体配置去google吧,有一点需要注意的是,如果同时配置了 Xdebug的话,在php.ini文件中,需要在Xdebug之前加载Zend OPcache extension扩展。

Built-in HTTP server

PHP从5.4.0引入了内置的HTTP server,所以我们在不配置Apache或者nginx的情况下就直接预览PHP程序。

<br>Remember, the PHP built-in server is a web server. It speaks HTTP, and it can serve static assets in addition to PHP files. It's a great way to write and preview HTML locally without installing MAMP, WAMP, or a heavyweight web server. <br>

要使用内置的HTTP server非常简单,在工程的根目录下,执行下面的命令即可:

<code class="language-bash hljs ">php -S localhost:<span class="hljs-number">4000</span></code>

如果要让本地网络的其他设备访问PHP web server,我们可以这么启动:

<code class="language-bash hljs ">php -S <span class="hljs-number">0.0</span>.<span class="hljs-number">0.0</span>:<span class="hljs-number">4000</span></code>

如果我们希望通过 PHP INI 配置文件去做一些特殊配置,可以通过下面命令来启动:

<code class="language-bash hljs ">php -S localhost:<span class="hljs-number">8000</span> -c app/config/php.ini</code>

我们也可以通过Router Scripts来实现一些特殊的路由需求,可以通过下面的命令启动:

<code class="language-bash hljs ">php -S localhost:<span class="hljs-number">8000</span> router.php</code>

在PHP代码中,我们可以通过php_sapi_name()来判断:

<code class="language-php?linenums hljs xml"><span class="php"><span class="hljs-preprocessor"><?php</span><span class="hljs-keyword">if</span> (php_sapi_name() === <span class="hljs-string">'cli-server'</span>) {        <span class="hljs-comment">// PHP web server</span>} <span class="hljs-keyword">else</span> {        <span class="hljs-comment">// Other web server</span>}</span></code>

Part 2. Good Pratices

Standards

PHP-FIG

PHP-FIG (PHP Framework Interop Group): The PHP-FIG is a group of PHP framework representatives who, according to the PHP-FIG website, "talk about the commonalities between our projects and find ways we can work together."

PHP-FIG是由很多不同PHP framework开发者组成的一个开放组织,他们提出的recommendations,不是标准或也不是要求,更像是best pratices的建议集合。不过,目前比较流行大多是PHP框架,比如Laravel或Symfony,都遵守了这些recommendations,所以这个感觉更像是Modern PHP事实上的标准,如果要使用PHP的很多工具和庞大的各种开源库,最好采用这个标准。

The PHP-FIG's mission is framework interoperability. And framework interoperability means working together via interfaces, autoloading, and style.
正如下面所说,PHP-FIG的使命就是不同framework之间的互通,让不同框架可以很容易结合在一起使用。而实现互通目前主要通过三个方面来入手:interfaces, autoloading, style:

  • Interfaces: Interfaces enable PHP developers to build, share, and use specialized components instead of monolithic frameworks,基于interfaces,我们可以做到直接使用某个框架的某个组件,比如Laravel的HTTP的处理部分就是直接使用 Symfony Frameworks的 symfony/httpfoundation 组件,而不用把整个Symfony都集成到Laravel之内。
  • Autoloading: PHP frameworks work together via autoloading. Autoloading is the process by which a PHP class is automatically located and loaded on-demand by the PHP interpreter during runtime,在autoloading标准出来之前,PHP组件和框架都是基于 \__autoload()或spl_autoload_register() 方法来实现自己独特的autoloaders,所以我们要使用一个第三方组件的时候,需要首先去研究一下它的autoloaders的实现。
  • Style: PHP frameworks work together via code style.

PSR

PSR是 PHP standards recommendation的缩写,是PHP-FIG提出的recommendations文档,例如PSR-1,PSR-2等。每个PHP-FIG recommendation都是为了解决某个大多数PHP框架开发中常遇到的问题而提出的。

目前在PHP-FIG的官方网站上,http://www.php-fig.org/psr/ ,可以看到所有的recommendations,目前被采用的有下面几个:
这里写图片描述

具体的PSR文档内容,可以参考官方网站,PSR-1/2/3/4 几个文档有中文翻译:

文档 原文 中文翻译
PSR-1 Basic Coding Standard https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md https://segmentfault.com/a/1190000002521577
PSR-2 Coding Style Guide https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md https://segmentfault.com/a/1190000002521620
PSR-3 Logger Interface https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md https://segmentfault.com/a/1190000002521644
PSR-4 AutoLoading Standard https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md https://segmentfault.com/a/1190000002521658

PSR-1 Basic Coding standard

PHP tags : 使用

PSR-2 Strict Code Style

Implement PSR-1 : 要求必须采用PSR-1
Indentation: 采用4个空格字符作为缩进
Files and lines : 必须使用Unix linefeed(LF)作为结尾;文件最后必须以空行作为结束;不能使用尾部 ?> PHP tag;每行尽量不要超过80个字符,最多不能超过120个字符;每行结尾不能包含空格;
Keywords: 所有的PHP关键字都必须小写
Namespaces: 每个namespace声明后面都必须跟着一个空行;使用use来import or alias namespaces的时候,必须在use声明后面跟一个空行;
Classes: 定义类时,开始的大括号(opening bracket)必须新起一行,结束的大括号(closing bracket)必须在类体定义后面新起一行;extents/implements关键字必须跟在类名定义的后面;例如:

<code class="language-php?linenums hljs xml"><span class="php"><span class="hljs-preprocessor"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">My</span>\<span class="hljs-title">App</span>;<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Administrator</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">User</span> {</span>    <span class="hljs-comment">// Class definition body</span>}</span></code>

Methods: 方法定义的大括号规则与类定义类似,opening brackets和closing brackets都必须新起一行。
Visibility: 对类中定义的全部property和method都必须声明可见性(visibility),可见性是public, protected, private其中的一个;abstract / final 必须写在visibility之前;static必须写在visibility之后;
Control structures : 所有的control structure keyword (if/elseif/else/switch/case/while/do while/for/foreach/try/catch)的后面都必须一个空字符;大括号的规则与class定义不同,opening brackets跟control structure keyword必须在同一行,而closing bracket必须另新一行;

我们可以通过IDE的格式化工具来让代码格式化,实现PSR-1和PSR-2的code style。我经常使用的工具PHPStorm就可以设置。还有一些其他工具,比如 PHP-CS-Fixer 或 PHP Code Sniffer

PSR-3 Logger Interface

PSR-3 is an interface, and it prescribes methods that can be implemented by PHP logger components.

PSR-4 Autoloaders

An autoloader is a strategy for finding a PHP class, interface, or trait and loading it into the PHP interpreter on-demand at runtime. PHP components and frameworks that support the PSR-4 autoloader standard can be located by and loaded into the PHP interpreter with only one autoloader.

关于PSR-4,看官方文档之后感觉理解很困惑,本书的作者的解释就非常简洁:
The essence of PSR-4 is mapping a top-level namespaces prefix to a specific filesystem directory.,简单来说,就是设定了一个namespaces前缀和某个特定的文件目录之间的映射关系,然后在这个namespace前缀之下如果还有更多的sub namespace,这些sub namespaces就会跟这个特定的目录下面的子目录一一映射起来。例如,\Oreilly\ModernPHP namespace与 src/ 物理路径一一映射,那么\Oreilly\ModernPHP\Chapter1对应的文件夹就是src/Chapter1,而\Oreilly\ModernPHP\Chapter1\Example类对应的文件路径就是src/Chapter1/Example.php文件。

PSR-4 lets you map a namespace prefix to a filesystem directory. The namespace prefix can be one top-level namespace. The namespace prefix can also be a top-level namespace and any number of subnamespaces. It's quite flexible.

Components

Components

Modern PHP is less about monolithic framework and more about composing solutions from specialized and interoperable components.

What Are Components?A component is a bundle of code that helps solve a specific problem in your PHP application.

框架与Components:如果我们正在创建一个小项目,可以直接使用一些PHP Components集合来解决问题;如果我们正在进行一个多人合作开发的大项目,我们可以通过使用一个Framework;但这都不是绝对的,应该根据具体问题来解决。

Packagist:跟其他语言的包管理机制一样,例如Maven,也有一个网站 https://packagist.org/ 让我们搜索我们需要的PHP Components的相关信息。总所周知的原因,Packagist在国内很不稳定,可以使用国内的全量镜像来代替,http://www.phpcomposer.com/ 。

Composer

Composer is a dependency manager for PHP components taht runs on the command line,跟其他现代语言一样,PHP使用Composer来做依赖管理,类似的有iOS中的Cocoapods,Android中的Maven/gradle,前端的npm,ruby的gem,这些工具可以大大简化我们管理第三方库的成本。于是,当我们在Packagist上面找到我们需要的Components之后,就可以通过Composer来使用这个库。

当我们使用Composer来添加第三方Component的时候,Composer除了会自动帮我们下载需要的PHP Components之外,还会自动帮我们创建一个符合PSR-4的Autoloader。

跟Cocoapods类似,Cocoapods使用Podfile来指定需要依赖的第三方库,以及保存有当前使用的具体的第三方库的版本号。所以我们需要把这两个文件都加入到版本控制中进行管理,确保不同成员/CI/开发环境等不同地方大家使用第三方库版本的一致性。对应Composer中的文件就是 composer.json以及composer.lock。这里需要注意的是composer install 和 composer update 命令的差别:
* composer install,不会安装比composer.lock中列出的更高版本的Components;
* composer update,会更新你的components到最新的稳定版,同时也会更新composer.lock文件为最新的PHP components版本号。

Semantic Versioning

Modern PHP Components 使用 Semantic Versioning scheme,同时包含了用小数点(.)分隔的三个数字,比如 1.13.2。同时,这个也是很多其他语言开源库的版本规则,对这个一直比较好奇,终于在Modern PHP中看到了相应的解释。

  • major release number:第一个数字是major release number,只有当PHP Component发生不再向前兼容的更新时,才需要增加这个版本号。
  • minor release number:第二个数字是minor release number,当PHP Component发生一些小的功能更新,并且没有破坏版本兼容时,增加这个版本号。
  • patch release number:最后一个数字是patch release number,当发生版本兼容的bug修复的时候,增加这个版本号。

Create PHP Components

这部分跟iOS创建自己的spec非常相似,并不是非常复杂的问题,参考书或者官方文档很容易就能发布

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 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尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

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

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경