Intereting Posts
Преобразование в и из индуистского календаря Конфликт версий Apache Как удалить ключ из json-ответа? Как получить доступ к сеансу пользователя Magento извне Magento? Есть ли у PHP виртуальная машина, например Java? ошибка phpunit при тестировании реализации с инъецированными зависимостями Неустранимая ошибка: исключить исключение «mysqli_sql_exception» с сообщением «Нет индекса, используемого в запросе / подготовленной заявке» Использование API Google Directory для извлечения всех пользователей в домене MYSQL возвращает пустой результат в PHP Как изменить URL-адреса в <a> на seo в Opencart 2.x автоматически? Как синхронизировать сеансы с помощью Amazon Web Services (AWS)? Codeigniter form_helper получает строки базы данных в значениях в меню выбора Предупреждение: PDOStatement :: execute (): SQLSTATE : недопустимый номер параметра: параметр не определен в … filetext Как добавить таблицу стилей для подтверждения? Расширение php_memcache WAMPSERVER

PHP-OOP расширяет два класса?

Я очень новичок в ООП, и теперь я пытаюсь написать некоторый PHP-класс для подключения к FTP-серверу.

class ftpConnect { private $server; private $user; private $password; private $connection_id; private $connection_correct = false; public function __construct($server, $user = "anonymous", $password = "anonymous@mail.com") { $this->server = $server; $this->user = $user; $this->password = $password; $this->connection_id = ftp_connect($this->server); $this->connection_correct = ftp_login($this->connection_id, $this->user, $this->password); if ( (!$this->connection_id) || (!$this->connection_correct) ){ echo "Error! Couldn't connect to $this->server"; var_dump($this->connection_id); var_dump($this->connection_correct); return false; } else { echo "Successfully connected to $this->server, user: $this->user"; $this->connection_correct = true; return true; } } } 

Я считаю, что этот класс класса на данный момент незначителен.

Основная проблема заключается в том, что у меня есть некоторые проблемы с пониманием идеи ООП.

Я хотел бы добавлять отправку писем каждый раз, когда код запускается. Я загрузил PHPMailer Class и расширил свой класс:

 class ftpConnect extends PHPMailer {...} 

Я добавил некоторые переменные и методы, и все работает так, как ожидалось.

Я подумал: почему бы не добавить все в базу данных. Каждый раз, когда пользователь работает над кодом, надлежащая информация должна храниться в базе данных.

Я мог бы отредактировать свой ftpConnect class и добавить базу данных, подключающуюся к конструктору, и некоторые другие методы для обновления таблиц. Но соединение с базой данных и все эти вещи могут использоваться другими классами в будущем, поэтому это определенно должно быть реализовано в отдельном классе. Но мой «основной» ftpConnect class уже расширяет один класс и не может распространять ни одного другого.

Я не знаю, как решить эту проблему. Может быть, мой ftpConnect class сложный, и я должен как-то разделить его на несколько меньших классов? Буду признателен за любую оказанную помощь.

Для начала я думаю, что у вас есть недостаток дизайна в вашем классе. Ваш конструктор выполняет работу. Это не то, что должен сделать конструктор в надлежащем ООП. Ваш конструктор должен просто установить свойства, и у вас должен быть отдельный метод connect() .

Второй ftpConnect никогда не должен расширять PHPMailer . Это две совершенно разные вещи. Читайте о принципе замещения Лискова, он является частью принципов SOLID .

Если вашему классу нужно что-то делать с базой данных или нужно отправлять письма, вам нужно вставлять эти экземпляры в свой класс, а не расширять их. Это называется инъекцией зависимостей, и это упростит последующие модульные тесты, поскольку вы можете легко использовать класс moker mailer или класс макетной базы данных.

Если вы хотите отправлять письма, иметь доступ к базе данных и использовать FTP, вам понадобится как минимум 3 разных (разделенных) класса (возможно, даже больше, чтобы сделать некоторое сопоставление для db и т. Д.). В принципе каждый класс должен иметь одну ответственность и только одну. Это называется принципом единой ответственности .

Для некоторых общих ссылок см.

  • Руководство: запись тестового кода
  • Google Clean Code Talks

Вероятно, это вопрос композиции над наследованием. Посмотрите эту предпочтительную композицию над наследованием? Просто используйте почтовый объект внутри вашего класса, а то же, что и для БД, а не для вашего класса, распространяющего любой из них.

 class my_class { private $mailer; public function __constructor() { $this->mailer = new Mailer(); } } 

Для части сохранения базы данных вы можете создать отдельный класс, который имеет соединение с вашей базой данных. Вы можете передать экземпляр этого класса в свой класс ftpConnect через его конструктор. Дайте вашему классу fptConnect свойство, в котором вы можете сохранить этот новый объект базы данных, таким образом вы можете получить доступ к этому объекту во всем классе ftpConnect .

В вашем классе ftpConnect настоящее время есть конструктор, который либо вернет true либо false , не позволяйте конструктору возвращать какое-либо значение, потому что ему нужно вернуть экземпляр класса ftpConnect, который вам нужно сохранить внутри переменной. Таким образом, вы можете установить фактическое соединение в отдельном методе. Таким образом, ваш класс может выглядеть примерно так.

 class FtpConnect { private $server; private $user = "anonymous"; private $password = "anonymous@mail.com"; private $connection_id; private $connection_correct = false; //this will take care of the storage private $database_handler; public function __construct($server, $user, $password, $database_handler) { $this->server = $server; $this->user = $user; $this->password = $password; $this->database_handler = $database_handler; //store the appropriate data, this will be done everything a new instance is created $this->database_handler->store_data($data_to_store); } public function connect() { //data to store, everytime a connection is made $this->database_handler->store_data($data_to_store); $this->connection_id = ftp_connect($this->server); $this->connection_correct = ftp_login($this->connection_id, $this->user, $this- >password); if ( (!$this->connection_id) || (!$this->connection_correct) ){ echo "Error! Couldn't connect to $this->server"; var_dump($this->connection_id); var_dump($this->connection_correct); return false; } else { echo "Successfully connected to $this->server, user: $this->user"; $this->connection_correct = true; return true; } } } 

Конечно, это возможный способ сделать это, вероятно, будут гораздо более элегантные решения. Способ доставки почты может быть реализован с использованием той же концепции.

Со стороны это будет выглядеть примерно так

 $ftp = new FptConnect('server', 'user', 'password', new DbHandler('server', 'user', 'password', 'host')); $ftp->connect();