Я пришел из мира процедурного программирования, когда ассемблер стал моим первым языком, а PL/1 и Cobol были языками, с которых я узнал большинство моих (плохих) привычек.Структура ООП для старого процедурного программиста
Это мой первый пост здесь, поэтому, пожалуйста, примите мои извинения, если я не делаю это на 100% правильно.
Я переписываю наши интерфейсные и бэкэнд-системы от процедурного php к ООП, и я не совсем понимаю, какую структуру использовать.
В старой системе у нас есть несколько скриптов, которые включают в себя xxx.inc.php с используемыми функциями, и те xxx.inc.php, в свою очередь, включают в себя другие xxx.inc.php, такие как db.inc.php, api_pj.inc.php и т. д.
Попытка сделать это ООП, я создаю один файл для каждого класса и автоматически загружаю их, но я не могу понять, как обращаться с общими классами (база данных, подключение к внешним api и т. д.). При тестировании я использовал наследование, и он отлично работает, но он очень странный. Я не вижу, чтобы класс клиента был дочерним классом базы данных. Также я не понимаю, что нужно определить, а не. Должны ли быть определены все переменные в классах?
Приведенный ниже пример не работает, поскольку соединение с базой данных недоступно для класса Customer. Когда «клиент класса расширяет базу данных», все работает нормально, но я полагаю, что есть более правильный способ сделать это?
Отредактированный код ниже после ответа от Alex Андрей
the_example_page.php
// autoloader
spl_autoload_register(function ($class) {
require_once 'classes/' . $class . '.class.php';
});
// data for testing
$customer_id = '12090';
$order_id = '31480';
// db
$db = new DB();
$db_conn = $db->db_connect();
// get customer name data and print it:
$customer = new Customer($db_conn);
$customer_data = $customer->get_customer_info($customer_id);
print $customer_data['name'];
// get order date and print it:
$order = new Order($db_conn);
$order_data = $order->get_order_info($order_id);
print $order_data['date'];
DB.class.php
class DB
{
public function __construct() {}
public function db_connect()
{
static $db_conn;
if(!$db_conn)
{
$db_conn = pg_connect("dbname=database user=user password=PaSsWoRd");
}
return $db_conn;
}
public function db_exec($sql)
{
if(!$sql) return;
$db_conn = $this->db_connect();
$result = @pg_exec($db_conn,$sql);
if(!$result)
{
return;
}
$ret[result] = $result;
return $ret;
}
public function db_getrow(&$a)
{
# a bunch of stuff in real function, but here only a plain fetch_array as example
$ret = pg_fetch_array($a);
return $ret;
}
}
Customer.class.php
class Customer
private $conn;
{
public function __construct($db)
{
$this->conn=$db;
}
public function get_customer_info($customer_id)
{
return $this->conn->db_getrow($this->conn->db_exec("SELECT * FROM customer WHERE customerid = $customer_id;"));
}
public function get_all_customers($status)
{
return $this->conn->db_exec("SELECT * FROM customer WHERE status = $status;");
}
}
Order.class.php
class Order
{
private $conn;
{
public function __construct($db)
{
$this->conn=$db;
}
public function get_order_info($order_id)
{
return $this->conn->db_getrow($this->conn->db_exec("SELECT * FROM order WHERE orderid = $order_id;"));
}
public function get_all_orders($status)
{
return $this->conn->db_exec("SELECT * FROM order WHERE status = $status;");
}
}
Действительно, Cus tomer * не является * базой данных, поэтому он не должен наследовать его. Взгляните на *** зависимую инъекцию ***. Со стороны потребителя, которая выглядит как '$ db = новая база данных ('foo', 'bar'); $ cust = новый клиент ($ db); '. Еще лучше: '$ manager = new CustomerManager ($ db); $ cust = $ manager-> get (42); '. Посмотрите на шаблон * хранилища. * – deceze