懒惰和非正统的PHP编码
#网络开发人员 #教程 #php #learning
  • 在业内多年,我已经开发了人们所说的“时髦的节目习惯”。
  • 这是一些“时髦的编码”的快速共享,希望能使一些初学者的大脑挠痒痒。

(第1部分)核心类

打哈欠

// SOME.PHP
namespace SOMETHING;
class MYLIB { ... }

// ANOTHER.PHP
require "SOME.PHP";
$OBJECT = new SOMETHING\MYLIB();

lib-core.php

// COREBOXX CLASS
class CoreBoxx {
  public $modules = [];
  function load ($module) : void {
    require "LIB-$module.php";
    $this->modules[$module] = new $module($this);
  }
}

// COREBOXX OBJECT & LOAD MODULE
$_CORE = new CoreBoxx();
$_CORE->load("DB");
  • 对于那些迷路的人,$_CORE->load("DB")简单:
    • require "LIB-DB.php";
    • $_CORE->modules["DB"] = new DB($_CORE);
  • “数组中的对象”一开始似乎很愚蠢,但是这会实施“标准库格式”。
    • LIB-Module.php
    • Class Module extends Core { ... }
  • 以下更多技巧。

(第2部分)魔术指针链接

魔术

class CoreBoxx {
  function __get ($name) {
    if (isset($this->modules[$name])) { return $this->modules[$name]; }
  }
}
  • “默认情况下”,我们使用$_CORE->modules["DB"](或功能中的$this->modules["DB"])访问数据库模块。
  • 我们使用__get()将其“缩短”到$_CORE->DB$this->DB

魔术链接

// LIB-CORE.PHP
class Core {
  public $Core;
  function __construct ($core) { $this->Core =& $core; }
  function __get ($name) {
    if (isset($this->Core->modules[$name])) { return $this->Core->modules[$name]; }
  }
}

// LIB-DB.PHP
class DB extends Core {}
  • 请注意,$_CORE->modules["DB"] = new DB($_CORE)。是的,我们将$_CORE传递到new DB()
  • 这里发生了什么:
    • $_CORE->DB->Core =& $_CORE
    • 同样的魔术__get()技巧。在DB的所有功能中,$this->Core都会引用$_CORE

兄弟姐妹链接

// LET'S SAY, WE ADD A DUMMY FUNCTION TO THE DATABASE MODULE
class DB extends Core {
  function dummy {
    $this->Core->load("Mail");
    $this->Mail->send("TITLE", "MESSAGE", "JON@DOE.COM");
  }
}

重要部分,为什么我们将所有模块链接回核心:

  • $_CORE->DB可以访问核心。
  • $_CORE->DB也可以访问兄弟姐妹模块。
  • 不再受“分层oop”的约束。
  • 一次开发一个模块,可以由所有其他模块重复使用。
  • 不再需要“您必须加载999个不同的父级和特质”。

(第3部分)建筑商和破坏者

class DB {
  public $pdo = null;
  public $stmt = null;
  function __construct ($core) {
    parent::__construct($core);
    $this->pdo = new PDO(
      "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET,
      DB_USER, DB_PASSWORD, [
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    ]);
  }

  function __destruct () {
    if ($this->stmt!==null) { $this->stmt = null; }
    if ($this->pdo!==null) { $this->pdo = null; }
  }
}
  • 构造函数和破坏者经常被初学者忽略,但是它们非常有用。
  • 在此数据库类中,我们自动连接到new DB()上的数据库。
  • 当对象被摧毁时,破坏者关闭连接。

(第4部分)邪恶的“参数映射”

不!

// LET'S SAY WE SUBMIT A FORM TO SAVE A USER
$_CORE->load("User");
$result = $_CORE->User->save($_POST["name"], $_POST["email"], $_POST["password"], $_POST["id"]);

有效。但是,如果您必须“映射参数功能”一百万次,那将变得非常痛苦。

邪恶评估进行营救

class CoreBoxx {
  function autoCall ($module, $function, $mode="POST") {
    // (A) LOAD MODULE
    $this->load($module);

    // (B) GET FUNCTION PARAMETERS
    if ($mode=="POST") { $target =& $_POST; } else { $target =& $_GET; }
    $reflect = new ReflectionMethod($module, $function);
    $params = $reflect->getParameters();

    // (C) EVIL MAPPING
    $evil = "\$results = \$this->$module->$function(";
    if (count($params)==0) { $evil .= ");"; }
    else {
      foreach ($params as $p) {
        // (C1) POST OR GET HAS EXACT PARAMETER MATCH
        if (isset($target[$p->name])) { $evil .= "\$_". $mode ."[\"". $p->name ."\"],"; }

        // (C2) USE DEFAULT VALUE
        else if ($p->isDefaultValueAvailable()) {
          $val = $p->getDefaultValue();
          if (is_string($val)) { $evil .= "\"$val\","; }
          else if (is_bool($val)) { $evil .= $val ? "true," : "false," ; }
          else { $evil .= ($val===null ? "null," : "$val,"); }
        }

        // (C3) NULL IF ALL ELSE FAILS
        else { $evil .= "null,"; }
      }
      $evil = substr($evil, 0, -1) . ");";
    }

    // (C4) EVIL RESULTS
    eval($evil);
    return $results;
  }
}

// YES!
$_CORE->autoCall("User", "save");

“专家”,您想要的一切。我很懒。

(第5部分)“通用”错误处理程序

class CoreBoxx {
  function ouch ($ex) {
    // SAVE $EX TO FILE? DATABASE?
    // AUTO SEND EMAIL ON CRITICAL STOPS?
    // SHOW YOUR OWN CUSTOM ERROR MESSAGE
  }
}

function _CORERR ($ex) { global $_CORE; $_CORE->ouch($ex); }
set_exception_handler("_CORERR");
  • 最后一点,我们可以在PHP中进行“全局捕获”(对于所有未接收的例外)。
  • 使用它来自定义您的“死亡蓝屏”。
  • 保留错误日志,甚至在关键失败中发送警告消息。

(额外)结局

这就是此压缩共享会话的全部。

  • 当然,没有一个“完美系统”之类的东西。
  • 受到建设性的批评。随时不同意我的时髦编码。
  • 是的,Core Boxx是一个“真正的PHP框架”。