首页 > 后端开发 > php教程 > PHP 框架:需要避免的隐藏错误

PHP 框架:需要避免的隐藏错误

Susan Sarandon
发布: 2025-01-04 12:16:35
原创
952 人浏览过

PHP Frameworks: hidden errors to avoid

Symfony(撰写本文时为 7.2)或 Laravel 等框架是高度可定制的,并且无论您的经验和技能如何,都鼓励良好的实践。

但是,您仍然可能会引入设计、安全或性能问题。

Symfony:不要直接调用 $container

❌ 这是一个经典但仍然被开发人员大量使用的:

 class LuckyController extends AbstractController
  {
      public function index()
       {
        $myDependency = $this->container->get(MyDependencyInterface::class);
        // 
       }
登录后复制
登录后复制

这是可能的,因为父 AbstractController 将 $container 定义为 protected:

protected ContainerInterface $container;
登录后复制
登录后复制

来源:Symfony - GitHub

虽然它确实有效,但由于多种原因,这是一个不好的做法:

  • 它会损害可读性
  • 测试更难
  • 它依赖于全局状态($container)
  • 随着 Symfony 的发展,它可能会在未来导致不兼容问题

✅ 在构造函数中使用依赖注入:

 class LuckyController extends AbstractController
  {
      public function __construct(private MyDependencyInterface $myDependency) {}
登录后复制
登录后复制

Eloquent ORM:不要盲目使用原始查询

Eloquent 允许非常方便地编写 SQL 查询。

开发人员可以使用 PHP 包装器与数据库实体交互,而不是直接编写 SQL 查询。

它还在后台使用 SQL 绑定,因此即使输入不受信任,您也可以免费获得注入保护:

User::where('email', $request->input('email'))->get();
登录后复制

❌但是,当您使用像 whereRaw 这样的帮助程序时,您可能会引入漏洞:

User::whereRaw('email = "'. $request->input('email'). '"')->get();
登录后复制

✅ 至少,始终使用 SQL 绑定:

User::whereRaw('email = :email', ['email' => $request->input('email')])->get();
登录后复制

注意:上面的例子没有意义,但它让事情变得简单。在现实世界的用例中,您可能需要 whereRaw 来进行优化或实现非常具体的 where 条件。

Laravel:CSRF 怎么样?

通过 CSRF 攻击,黑客迫使最终用户在他们当前经过身份验证的应用程序上执行不需要的操作。

Laravel 有一个内置机制来防范这种情况。

粗略地说,它添加了一个与您的请求一起发送的令牌(隐藏字段),因此您可以验证“经过身份验证的用户是实际向应用程序发出请求的人。”

很公平。

❌但是,某些应用程序会跳过此实现。

✅ 是否应该使用内置中间件与此处无关,但请确保您的应用程序免受 CSRF 攻击。

您可以阅读此页面以了解有关 Laravel 中实现的更多详细信息。

也请确保 AJAX 请求的安全。

Eloquent ORM:查询没有“自动”优化

Eloquent 允许急切/延迟加载,并支持各种优化,例如查询缓存、索引或批处理。

但是,它并不能防止所有性能问题,尤其是在大型数据集上。

❌ 这种循环并不罕见:

 class LuckyController extends AbstractController
  {
      public function index()
       {
        $myDependency = $this->container->get(MyDependencyInterface::class);
        // 
       }
登录后复制
登录后复制

但它可能会导致内存问题。

✅ 如果可能,更好的方法是利用 Laravel 集合和块等帮助器:

protected ContainerInterface $container;
登录后复制
登录后复制

查看文档了解更多详细信息。

注意:它有效,但不要忘记这些助手只是为了简化实现,因此您必须监视缓慢的查询和其他瓶颈。

Symfony:SRP 服务

正如文档所述:

有用的对象称为服务,每个服务都位于一个非常特殊的对象中,称为服务容器。容器允许您集中构造对象的方式。它让您的生活更轻松,促进强大的架构并且速度超级快!

换句话说,您将编写自定义服务来处理您的应用程序的特定职责。

❌文档是正确的。它旨在促进强大的架构,但阅读违反单一职责原则 (SRP) 的服务并不罕见:

 class LuckyController extends AbstractController
  {
      public function __construct(private MyDependencyInterface $myDependency) {}
登录后复制
登录后复制

✅ 你必须尊重这个原则。测试和维护会更容易。

Symfony:公共服务与私人服务

❌ 使用 Symfony,您可以使用 $container->get('service_id') 来调用任何公共服务。

我们之前看到,像这样调用 $container 被认为是一种不好的做法。

您可能无法抗拒将所有服务公开的诱惑,因此您几乎可以在项目中的任何地方通过它们的 ID 检索它们。

不要这样做。

✅ 相反,将大多数自定义服务保持私有并使用依赖项注入。

包起来

希望您能够避免我所说的框架的“潜在错误”或“隐藏错误”。

如果您不知道如何实现它,请相信该框架,但请注意某些机制可能默认情况下未启用。

以上是PHP 框架:需要避免的隐藏错误的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板