小编Jon*_*han的帖子

PHP中的正确存储库模式设计?

前言:我正在尝试在具有关系数据库的MVC架构中使用存储库模式.

我最近开始用PHP学习TDD,并且我意识到我的数据库与我的应用程序的其余部分非常接近.我已经阅读了有关存储库和使用IoC容器将其"注入"我的控制器的内容.很酷的东西.但是现在有一些关于存储库设计的实际问题.考虑以下示例.

<?php

class DbUserRepository implements UserRepositoryInterface
{
    protected $db;

    public function __construct($db)
    {
        $this->db = $db;
    }

    public function findAll()
    {
    }

    public function findById($id)
    {
    }

    public function findByName($name)
    {
    }

    public function create($user)
    {
    }

    public function remove($user)
    {
    }

    public function update($user)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

问题#1:字段太多

所有这些find方法都使用select all fields(SELECT *)方法.但是,在我的应用程序中,我总是试图限制我获得的字段数量,因为这通常会增加开销并减慢速度.对于那些使用这种模式的人,你如何处理这个?

问题#2:方法太多了

虽然这个类现在看起来不错,但我知道在现实世界的应用程序中我需要更多的方法.例如:

  • findAllByNameAndStatus
  • findAllInCountry
  • findAllWithEmailAddressSet
  • findAllByAgeAndGender
  • findAllByAgeAndGenderOrderByAge
  • 等等.

如您所见,可能存在非常长的可能方法列表.然后,如果您添加上面的字段选择问题,问题就会恶化.在过去,我通常只是将所有这些逻辑放在我的控制器中:

<?php

class MyController
{
    public function users()
    {
        $users = User::select('name, email, status') …
Run Code Online (Sandbox Code Playgroud)

php database repository repository-pattern laravel

265
推荐指数
4
解决办法
6万
查看次数

PHP中模型验证的最佳方法?

我了解到,通常有很多方法可以解决一个编程问题,每种方法通常都有自己的好处和负面影响.

我今天要确定的是在PHP中进行模型验证的最佳方法.使用一个人的例子,我概述了我过去使用的四种不同的方法,每种方法包括类和一个用法示例,以及我喜欢和不喜欢的每种方法.

我的问题是:你觉得哪种方法最好?或者你有更好的方法吗?

方法#1:使用模型类中的setter方法进行验证

好的

  • 简单,只有一个班级
  • 通过抛出异常,类永远不会处于无效状态(除了业务逻辑,即死亡在出生之前)
  • 不必记得调用任何验证方法

坏的

  • 只能返回1个错误(通过Exception)
  • 需要使用异常并捕获它们,即使错误不是很特殊
  • 只能对一个参数进行操作,因为其他参数可能尚未设置(无法比较birth_datedeath_date)
  • 由于大量验证,模型类可能很长
class Person
{
    public $name;
    public $birth_date;
    public $death_date;

    public function set_name($name)
    {
        if (!is_string($name))
        {
            throw new Exception('Not a string.');
        }

        $this->name = $name;
    }

    public function set_birth_date($birth_date)
    {
        if (!is_string($birth_date))
        {
            throw new Exception('Not a string.');
        }

        if (!preg_match('/(\d{4})-([01]\d)-([0-3]\d)/', $birth_date))
        {
            throw new Exception('Not a valid date.');
        }

        $this->birth_date = $birth_date;
    }

    public function set_death_date($death_date)
    {
        if (!is_string($death_date)) …
Run Code Online (Sandbox Code Playgroud)

php validation model

35
推荐指数
1
解决办法
4591
查看次数

何时使用filter_input()

这个问题最初是在这里的评论中提出的.

filter_input()仍然是必要的,如果你正在使用参数化查询,并用htmlspecialchars()打印所有用户提供的数据之前?

对我来说似乎没必要,但我总是被告知"过滤输入,逃避输出".因此,除了数据库(或其他形式的存储)之外,是否还需要过滤输入的数据?

php security

27
推荐指数
2
解决办法
3万
查看次数

在PHP中设计服务层类

最近介绍Jani Hartikainen的服务层,讨论了如何在MVC应用程序中最好地处理表单数据.之后做一些阅读我真的可以看到这种做法的好处.我的问题是:

如何构建服务类?

  • 首先,user_service()我的user()模型是一个合适的类名还是另一个标准?
  • 由于我服务中的方法只会执行一项任务,因此认为这些方法总是可以的static function吗?服务类不代表数据,而是一系列动作,所以这似乎是合适的.
  • 服务方法应该只接受一个argument,这将是一个array

考虑表单已将数据发布到控制器以保存用户数据:

<?php

    class form_controller extends controller
    {

        public function process_submit()
        {
            if(user_service::update_preferences($_POST))
            {

                echo json_encode(array('success' => true));
            }
            else
            {
                echo json_encode(array('success' => false));
            }
        }

    }

    class user_service
    {

        // Accepts array()
        public static function update_preferences($fields)
        {

            // Check for required fields
            if((
                isset($fields['firstname']) and
                isset($fields['lastname']) and
                isset($fields['email'])
                ) == false
            {
                return false;
            }

            // …
Run Code Online (Sandbox Code Playgroud)

php model-view-controller service-layer

14
推荐指数
1
解决办法
6808
查看次数

数据库结果作为对象或数组?

这个问题类似于PHP中的Mysql结果 - 数组或对象?但是,我的问题扩展到那里讨论的内容.

我正在尝试确定哪种格式更适合处理数据库结果:对象或数组.我不关心性能(据我所知,它没有什么区别).我的重点更多的是显示结果 - 不创建,更新或删除它们.

到目前为止,我总是使用像mysqli_fetch_objectPDO这样的函数来使用对象fetchObject.这通常很好用,直到我开始做连接.连接导致奇怪的对象,这些对象是来自两个或多个表的字段的混合.我的代码很快就开始变得混乱.

我应该注意,我正在分配特定的类名,而不是坚持默认stdClass.我这样做,以便我可以访问我在我的类中创建的任何帮助方法.例如:

foreach ($members as $member)
{
    echo $member->full_name();
    echo $member->age();
}
Run Code Online (Sandbox Code Playgroud)

为了清楚起见,我正在考虑为我的所有数据库结果移动到数组.从我读过的其他人也这样做.但是,这让我没有简单的方法来访问我的帮助方法.

使用上面的例子,我想我可以输出名字和姓氏而不是使用full_name()方法,这不是什么大问题.至于age()方法,我想我可以创建一个通用实用程序类并将其放在那里.

我的问题:

  1. 如果使用(模型)对象,如何处理连接?
  2. 如果使用数组,那么如何处理辅助方法?

php mysql

11
推荐指数
2
解决办法
6911
查看次数

在PHP Web应用程序中使用依赖项注入

我最近读了很多关于依赖注入的内容,理论上它已经很有意义了.容易测试,单一责任类的想法听起来很聪明.但是,我正在努力解决这个问题.

我正在开发一个PHP Web应用程序,它现在有一个CMS组件,并且是由数据库驱动的.在CMS中,您可以创建页面,页面本身使用各种小部件构建.小部件可以是直接HTML(来自WYSIWYG编辑器),也可以更复杂,如照片库.这是重要的部分,照片库小部件依赖于其他数据库模型,如PhotoGalleryPhotoGalleryImages为了正常运行.

根据MiškoHevery,我不应该通过我的应用程序的不同层传递对依赖项的引用.相反,每个类应该简单地"询问"它所需的任何依赖性.使用他的例子,这是看起来如何:

$db = new Database()
$repo = new UserRepository($db);
$page = new LoginPage($repo);
Run Code Online (Sandbox Code Playgroud)

虽然我可以看到这对我的应用程序的服务层工作正常,但我真的不明白这对我的值对象/实体如何工作.在我看来,这种模式要求我在我的应用程序的最高层实例化我的所有模型.但是,当我需要我的页面类告诉我需要实例化哪些小部件时,我如何在该级别实例化我的所有小部件?如果不知道我正在创建什么小部件,我怎么知道需要创建和注入哪些小部件依赖?

从理论上讲,DI对我来说很有意义.但是,实际上在我的新Web应用程序中实现此模式更加困难.对于DI和IoC,还有一些我缺少的东西吗?谢谢!

更新:对Tandu的回应

非常感谢Tandu的回应.我认为DI在这里可能实际上不是我的问题,因为我认为我非常清楚它是什么,无论是构造函数还是setter注入,还是使用容器或穷人的方式完成.我认为正在发生的事情是DI正在挑战我重新思考我目前的编程方式.我认为我的OOP设计是个问题.为了说明这一点,以下是我通常编程此问题的方法:

class Page
{
    public $id;
    public $name;

    public function widgets()
    {
        // Perform SQL query to select all widgets
        // for this page from the database, and then
        // return them as Widget objects.
    }
}

interface Widget
{
    public $id;
    public $page_id;
    public $type;

    public function widgetize();
}

class PhotoGallery_Widget implements Widget
{ …
Run Code Online (Sandbox Code Playgroud)

php dependency-injection

10
推荐指数
1
解决办法
444
查看次数

了解IoC,DI和参考方法

我正在学习依赖注入和控制反转,我想我已经开始理解它是如何工作的:

  • 对象不应该关注自己的依赖项的创建
  • 应该将依赖关系传递给对象(通过构造函数或setter方法)
  • DI容器可以完成创建具有所有必需依赖项的对象的工作

如果这一切都正确,我可以不再使用我在对象中称为"参考方法"的东西吗?

这是我的参考方法的意思.说我有两个家庭和家庭成员模特.我发现创建引用与该模型相关的对象的方法非常有用.在下面的示例中,在呼叫时$family->members(),我可以快速访问所有家庭成员.但是,这意味着我的family对象正在实例化family_member类......并且这不会违反IoC的规则吗?

如果family_member该类具有超出family该类范围的依赖性,该怎么办?这里的输入会很受欢迎!

<?php

    class family
    {
        public $id;

        public function members()
        {
            // Return an array of family_member objects
        }
    }

    class family_member
    {
        public $family_id;
        public $first_name;
        public $last_name;
        public $age;
    }
Run Code Online (Sandbox Code Playgroud)

php dependency-injection inversion-of-control

8
推荐指数
1
解决办法
542
查看次数

配置PHP内置Web服务器

使用内置的PHP Web服务器时,如何设置配置选项,通常使用php.ini.htaccess文件设置?

php .htaccess configuration webserver

3
推荐指数
1
解决办法
1685
查看次数