关于PHP OOP代码的建议

时间:2012-01-06 11:39:56

标签: php oop

在PHP项目中,我有三层(逻辑)

用户界面

存放UI php页面的位置。例如: ManageUsers.php

代码

与系统相关的所有实体类。例如: User.php

DataAccess

实体类的数据访问类例如: UserDataAccess.php

因此,要从用户界面添加用户,我会创建用户类设置属性的实例&调用AddUser方法(在用户类中)。在AddUser方法中,它会创建 UserDataAccess 类&的实例。将相同的($ this)对象传递给 UserDataAccess Insert函数。它从用户对象属性&获取数据。更新表格。 (通过代码图层将状态返回 UI

我重复这个功能,如Edit&删除。

  1. 这是获得此CRUD功能的首选OOP方式,还是可以减少一层&结合代码& DataAccess 图层使其更简单?
  2. 是否可以在 ManageUser 页面中多次实例化用户类(一个用于添加,一个用于编辑等等)或者只需将其实例化一次一页?
  3. 对不起长度&问题的复杂性..提前感谢...

1 个答案:

答案 0 :(得分:1)

这是获得此CRUD功能的首选OOP方式,还是可以减少一层&结合Code& DataAccess层使它更简单?

3层方法(接口“U.I.”,业务逻辑“代码”和数据访问)是建议的做事方式。

你会发现有几个商业应用程序。使用您建议的“2层”方法。如果您认为应用程序将“增长”,则应使用3层。

但是,请记住,它的复杂性也会增加。

您可能还想获得(下载,开发,购买)一个单独的工具程序来读取数据库或数据访问,并从中生成实体类,而不是自己编写所有类。

如果可能,对“代码”或“业务逻辑”实体执行相同的操作。

还有一件事,就是避免将所有实体放在一个文件中。

而是使用每个实体的文件。为您的界面或“边界”类创建一个单独的“GUI”文件夹, “代码”类的文件夹,以及“数据访问”类的文件夹。

您的网站或应用程序可能很小,而且这些建议可能会非常复杂且不必要。

但是,根据经验,应用程序。往往会增长,甚至是“宠物”或“个人”网站,意外地可能会增长,并变得复杂。

即使是个人小项目,您也可以尝试使用这些建议,以便为大型网站或应用做好准备。

其他建议

我向同事学习一个技巧,使代码更易于维护,使用自动生成实体代码的程序,以及稍后不会创建这些类实体的实例,通常在3层方法中完成

相反,第二类实体是代码,通常是手动添加一些可能会定期更新的成员或功能。

因此第一个(父)类具有可以从数据库(或XML文件)获取的成员,而第二个(子)类具有可能无法从数据库获取的成员,并且还需要做了很多改变,需要“手工编码”。

示例:

(1)您有这样的数据库表(或XML文件或本地文件):

CREATE TABLE User
(
  integer UserKey primary key,
  varchar(20) UserAlias,
  varchar(250) UserPasword,
  integer UserIsActive, -- My D.B. doesn't support boolean
)

(2)您可以手动或工具生成这样的数据访问层实体:

abstract class FieldsUserDataAccessEntityClass
{
  /* integer */ protected $fieldUserKey = 0;
  /* string */ protected $fieldUserAlias = "";
  /* string */ protected $fieldUserPassword = "";
  /* integer */ protected $fieldUserIsActive = 0;

  /* integer */ public function CalculateNewKey();

  /* void */ public function Insert();
  /* void */ public function InsertWithKey(/* integer */ $newKey);

  /* void */ public function Update();

  /* void */ public function Delete();
} // class

此前一课通常直接使用(没有“抽象”功能)。

但是,建议是,在其他文件中,这个,(我跳过方法代码):

/* concrete */ class UserDataAccessEntityClass extends FieldsUserDataAccessEntityClass
{
  public /* integer */ function getUserKey();
  public function setUserKey(/* integer */ $newValue);

  public /* string */ function getUserAlias();
  public function setUserAlias(/* string */ $newValue);

  public /* string */ function getUserPassword();
  public function setUserPassword(/* string */ $newValue);

  public /* string */ function getUserPassword();
  public function setUserPassword(/* string */ $newValue);

  public /* bool */ function getUserIsActive();
  public function setUserIsActive(/* bool */ $newValue);
} // class

...
/* void */ function GlobalDoSomething()
{
  /* UserDataAccessEntityClass */ $CurrentUser = new UserDataAccessEntityClass();
    /* integer */ newKey = $CurrentUser->CalculateNewKey();

    $CurrentUser->setUserKey(newKey);
    $CurrentUser->setUserName("JohnDoe");
    $CurrentUser->setUserPassword("a9b8c7d6e5f4");
    $CurrentUser->setUserIsActive(true);

    $CurrentUser->Insert();
  $CurrentUser = null;
} // 
...

我使用从“整数”到“布尔”的“IsActive”字段的转换,例如, 可能是其他东西,如截断太长的字符串。

一些开发人员会抱怨,并建议在业务逻辑实体中执行此操作。

(3)您可以手动或工具生成这样的业务逻辑层实体:

abstract class FieldsUserLogicAccessEntityClass
{
  /* integer */ protected $fieldUserKey = 0;
  /* string */ protected $fieldUserAlias = "";
  /* string */ protected $fieldUserPassword = "";
  /* integer */ protected $fieldUserIsActive = 0;

  /* void */ public function DoSomeThing();
} // class

在其他文件中,这个(我跳过方法代码):

class UserLogicAccessEntityClass extends FieldsUserLogicAccessEntityClass
{
  public /* integer */ function getUserKey();
  public function setUserKey(/* integer */ $newValue);

  public /* string */ function getUserAlias();
  public function setUserAlias(/* string */ $newValue);

  public /* string */ function getUserPassword();
  public function setUserPassword(/* string */ $newValue);

  public /* string */ function getUserPassword();
  public function setUserPassword(/* string */ $newValue);

  public /* bool */ function getUserIsActive();
  public function setUserIsActive(/* bool */ $newValue);

  /* void */ public function DoAnotherThing();
} // class


...
/* void */ function GlobalDoSomething()
{
  /* UserLogicAccessEntityClass */ $CurrentUser = new UserLogicAccessEntityClass();
    $CurrentUser->setUserName("JohnDoe");
    $CurrentUser->setUserPassword("a9b8c7d6e5f4");

    if ($CurrentUser->TryLogin())
    {
      echo "Welcome !!!";
    }
    else
    {
      echo "Security Alert !!!";
    }
  $CurrentUser = null;
} // 
...

当您必须添加或删除或更新数据库中的字段时,这些方法会有很大帮助,但是,它更复杂,因此需要实体生成器。

一个工具生成“带字段的抽象”实体类的想法, 并在需要时手动修改“具体子”实体类。

在现实世界的编程中,手动修改hte实体会发生很多事情。

是否可以在ManageUser页面中多次实例化User类(一个用于Add的实例,一个用于Edit等等)或者只应该为一个页面实例化一次?

很好,实例化一个实体类,好几次,但更常见的是,将它们作为临时对象的int方法。对于像“当前登录的用户”这样的对象,您可以使用“单例”对象。