аргументируй. Там не сказано получение файлов, там сказано : Я написал как они и просили, я описал если они скажут какой тип данных передаётся то он вызовет определённый метод, ток как будет получатся файл это уже десятый вопрос, его можно получить хоть file_get_contents хоть через форму. Я считаю второе задание решено верно, если нет надо чётче давать инструкции если нет полного тз, то выдумывать можно что угодно. Ты имеешь ввиду количество дубликатов по полю логин или что хотят они какая цель приследуется? Ну в любом случаю по WHERE login=:login а там уже можно хоть COUNT считать сколько их или чего хотите, не понятно. Но это всё мелочи мне просто это как плевок в лицо, что меня отправляют читать курсы про циклы в php --- Добавлено --- Не понял ты о чём? --- Добавлено --- Смотря как файл отдавать, если это file_get_content то лучше указать в ручную, если же ты получаешь глобальный массив _FILES то тогда можно и внутри автоматически, но мне кажется по логике вещей это разные классы и они должны быть разделены один получение файлов, а другой это класс работы с файлом. Тебе не кажется что логика здесь должна быть разделена именно так?
Тут не надо выдумывать ничего, твоя задача показать своё ООП согласно условиям. К примеру так (очень образно). PHP: class Worker { protected $filePath = ''; public function __construct(string $filePath) { $this->filePath = $filePath; } public function handle() { $adapter = $this->getFileAdapter(); $adapter->toArray($this->filePath); } protected function getFileExt() { return 'ext'; } protected function getFileAdapter() { $ext = $this->getFileExt(); if ($ext === 'xlsx') { return new XLSXAdapter(); } throw new Exception('File adapter not found!'); } } interface FileAdapter { public function toArray($filePath) : array ; }; class XLSXAdapter implements FileAdapter { public function toArray($filePath) : array { return []; } }; --- Добавлено --- Там прямо сказано про расширение. Получили путь к файлу - работаем. Всё.
Стоп стоп, а если файл передаётся путём upload и лежит в массиве $_FILES То твоя конструкция не верна.
Да ладно, что там непонятного-то? PHP: public function dataType($typeFile) { if (empty($typeFile)) { return false; } switch ($typeFile) { case 'xml': $this->xml = true; break; case 'doc': $this->doc = true; break; case 'txt': $this->txt = true; break; default: return false; } return $this; } Такой код любой чел, знакомый с ООП, тебе забракует. Где полиморфизм?
@mkramer ладно я успокоился меня просто бесит что я пролетел и я вроде понимаю что такое полиморфизм и пишу сейчас алгоритм тока где то чё то не догоняю, пытаюсь реализовать на интерфейсах но не могу понять как проверить и какой именно нужно метод вызвать для этого. --- Добавлено --- PHP: class HandleFile { public function __construct($typeArray) { foreach ($typeArray as $type) { if ($type instanceof \intHandleFile) { $type->HandleType(); } } } } interface intHandleFile { public function HandleType() ; } class Xml implements intHandleFile { public $type; public $file; public function HandleType () { if ($this->type === true) { echo $this->type; } } } class Doc implements intHandleFile { public $type; public $file; public function HandleType () { if ($this->type === true) { echo $this->type; } } } class Txt implements intHandleFile { public $type; public $file; public function HandleType () { if ($this->type === true) { echo $this->type; } } } --- Добавлено --- Я полагаю вторая задача типа должна решаться как то так? --- Добавлено --- Чутка переделал, на вот так: PHP: class HandleFile { static public function handle($typeArray) { foreach ($typeArray as $type) { if ($type instanceof \intHandleFile) { $type->HandleType(); } } } } interface intHandleFile { public function HandleType(); } class Xml implements intHandleFile { private $type; private $file; public function __construct($type, $file) { $this->type = $type; $this->file = $file; } public function HandleType() { if ($this->type === 'xml') { echo $this->type; } } } class Doc implements intHandleFile { private $type; private $file; public function __construct($type, $file) { $this->type = $type; $this->file = $file; } public function HandleType() { if ($this->type === 'doc') { echo $this->type; } } } class Txt implements intHandleFile { private $type; private $file; public function __construct($type, $file) { $this->type = $type; $this->file = $file; } public function HandleType() { if ($this->type === 'txt') { echo $this->type; } } } $docOne = new Doc('doc', file_get_contents(__DIR__ . '/doc.doc')); $arr = [ $docOne ]; HandleFile::handle($arr);
Да не, это скучно. Тебе же @romach приводил решение. Должен быть набор классов для обработки каждого типа файла, и фабрика, которая получает файл, выделяет расширение и на его основе создаёт нужный класс. Тогда это будет расширяемо - при добавлении новых классов меняется только фабрика. А с PHP мы вообще можем сделать, чтоб ничто менять не нужно было, с его способностью брать имя класса из строковой переменной. Я обычно так и делаю. PHP: abstract class FileHandler { abstract function handle($file); static public function factory($fname) { $className = ucfirst(strtolower(path_info($fname, PATHINFO_EXTENSION))) . "Handler"; if (!class_exist($className)) { throw new Exception("Undefined handler"); } return new $className; } } class TxtHandler extends FileHandler{ function handle($file) { echo "$file - это TXT"; } } class XlsHandler extends FileHandler{ function handle($file) { echo "$file - это XLS"; } } $fname = "/path/f.txt"; FileHandler::factory($fname)->handle($fname); Это - паттерн фабричный метод. --- Добавлено --- У Зандстры много примеров. Правда, там он использует switch, но даже со switch решение неплохо, поскольку он только в одном месте, и при расширении иерархии его нужно будет исправить один раз (и в . А этот вариант вообще не нужно исправлять. Добавляй классов сколько хочешь. --- Добавлено --- https://www.youtube.com/playlist?list=PLmqFxxywkatStbd9hdzVOS1hZa9dc56k4 - вот этот курс посмотри. Дядька правда джавист, но объясняет шикарно паттерны. Параллельно с Зандстрой хорошо идёт. Я сам не каждый раз применяю паттерны, иногда просто лень Но знать надо. --- Добавлено --- Весь смысл ООП в том, чтобы не проверять, какой метод вызывать. Все паттерны - именно об этом. Иначе классы мало смысла имеют - можно с тем же успехом просто разбить программу на модули, будет тоже структуированно.
Ты слишком много не нужного тянешь от типа к типу, т.е. не используешь ООП как нужно. PHP: <?php abstract class Handler { abstract function read(); abstract function write(); static function getInstance($extension) { switch ($extension) { case "txt": return new TxtHandler(); case "xml": return new XmlHandler(); default : throw new Exception('Handler not found'); } } } class TxtHandler extends Handler { public function read() { echo "txt read()"; } public function write() { echo "txt write()"; } } class XmlHandler extends Handler { public function read() { echo "xml read()"; } public function write() { echo "xml read()"; } } $obj = Handler::getInstance('xml'); $obj->read(); $obj->write(); Тут важно позаботиться о инклуде файла класса, иначе опа. В этом случае ведь автолоад не сработает. Конечно я понимаю, что это не конечная реализация, но моя не успокоилась бы пока не написал, не знаю чего я такой придирчивый. @askanim, все примеры которые тут приводились, и решение этой тестовой задачи есть в книге "PHP Объекты, шаблоны и методики программирования" Мэтт Зандстра. Советую тебе его почитать. --- Добавлено --- Ах да, при использовании я забыл заключить в try catch для перехвата исключения.
С какой это радости он не сработает? Работает, проверено. Естественно, в реальных проектах я ещё правильное пространство имён подставляю Т.е. было бы PHP: $className = __NAMESPACE__ . '\Handlers\\' . ucfirst(strtolower(path_info($fname, PATHINFO_EXTENSION)))."Handler"; Автолоад для динамически сформированного имени тоже работает - а что, в фреймворках тоже switch() стоит, чтоб мои контроллеры грузить? Откуда они их имена знают? Особенно те, что роуты а-ля /controller/action вообще без моего участия разрешают в имя класса и функцию, к примеру Yii2.
@mahmuzar, @mkramer Не ну вы серьёзно? Вы думаете я не знаю что аткое полиморфизм и какими средствами в php можно его организовать, да сделать можно как угодно, я даже помню я создавал тему про интерфейсы где я предлогал собирать модели по инструкции однотипной. А именно вот здесь: https://php.ru/forum/threads/interfejsy.63084/ . Ещё раз только киньте в меня книгой зандстры, я её видел. Я полиморфизм на абстрактных классах прошёл ещё полтара года б*я тому назад. Просто я его на столько крайне редко юзаю что просто про него забыл. Но чтобы его заюзать должна быть прямо необходимость. --- Добавлено --- Можно я кого нибудь покусаю...
Спасибо. Я уже это услышал в первом твоём посте что там полиморфизм. И я тогда тут же начал писать код и потом прикрепил на что ты мне показал паттерн фабричный метод, мне понравилось, я решил только сделать его на интерфейсах а не на абстрактных чуть позже выложу времени мало надо в офис бежать. А потом вы ещё 10 раз обсмоковали и кинули книгой в меня, я ведь правильно показал полиморфизм когда прикрепил код? Скучно может быть но полиморфизм я привёл верно? да я не понятно зачем написал библиотеку. Хз как так вышло --- Добавлено --- этого я не знал паттерна. --- Добавлено --- Не хватка практического опыта К сожалению весь мой опыт это работа над собственными проектами либо же опыт работы на сообственных клиентов. Я бы хотел пойти в большую компанию для получения такого опыта. Но к сожалению пока не могу найти место.
Ну так, кинули книгой - потому что там ещё много интересного, помимо фабричного метода. Как и в лекциях джависта, которые кинул я Паттерны показывают как раз наиболее эффективное использование полиморфизма, а не просто что это такое. Я сам долго писал без них, пока в одном проекте не утонул в собственном говнокоде. Порождающие паттерны (синглтон, фабрика/фабричный метод, абстрактная фабрика) - это то, о чём надо всегда помнить. Да, есть несколько реализаций. Мне нравится фабричный метод в абстрактном родителе, можно вынести его в отдельный класс. Но, главное, чтоб клиенту, обращающемуся к фабрике, не приходилось самому заботится о том, какой класс почему надо создать. Сосредоточить логику выбора в одном месте. И вообще, не надо любую ссылку на учебный материал принимать за оскорбление В нашей профессии всё так быстро устаревает/меняется, что что-то читать нужно постоянно.
Это я в избранное добавил. Мне показал Игорёк ^^ Я вот сейчас пишу на нём библиотеки для работы с базой в нашем проекте --- Добавлено --- это точно
Когда то с этим у меня были проблемы, сейчас проверил, работает как надо. Вероятно, на тот момент я что-то делал не так).
@mkramer У меня оказывается есть купленный экземпляр книги зандстры Сегодня засел читать. Честно скажу чувак крут. Начал с 9 главы генерация объектов, мне даже в голову кое что не приходило что так можно делать --- Добавлено --- @human1 да книга крутая Она реально хороша) Я вот сижу читаю шаблоны проектирования и понимаю как круто можно на самом деле писать код)
Фабрика - чуть ли не самый широко известный. Она с синглетоном, наверное, на первых местах по популярности и наслышанности. Хотя, справедливости ради, то, что тут озвучивали, на самом деле не столько "фабрика", сколько "стратегия".
Я сегодня изучал зандстру, 9 главу всю изучил Очень инетресно. И теперь я не просто слышал об этих названиях, теперь ещё я знаю что это и как это, и в принципе не совсем конечно пока до конца - куда это)
Они все переплетены, но всё же функции создают объекты, выбирая подходящий. И никуда его не передают. А вообще, тут может быть всё вместе. Типа, какой-нибудь TableImporter получает либо CSVTableFile или XLSTableFile, которые соответственно реализуют либо построчное чтение CSV, либо построчное чтение Ёклселя. А два последних могут создаваться методом factory() абстрактного класса TableFile. Всё-таки пораждающие шаблоны всегда рассматриваются первыми, поскольку все эти стратегии и т.д. тоже надо где-то создавать
@mkramer а мне всё таки больше нравится использование интерфейсов чем абстрактных классов, ведь в принципе через них можно реализовать тоже что и делает зандстра с абстрактными) Ну правда будет ещё входящий класс)
Они взаимозаменяемые. В интерфейс не засунуть поведение, в абстрактный класс - засунуть. Хотя я иногда создаю интерфейс => абстрактный класс => Конкретная реализация. Всё зависит от задачи. Иногда я вообще пишу if, думаю, а хорошо бы тут стратегию. Потом думаю - здесь пока и иф неплохо смотрится, и оставляю так. Всё зависит от задачи. Чем сложнее задача, тем больше от этого всего пользы
Но только в не абстрактный метод. Интерфейс это, по-сути более строгая структура относительно абстрактного класса. И более молодая хронологически. Она не лучше абстракта и не хуже. Если понимаешь, что делаешь, не особо принципиально, что именно используешь. Разве что интерфейсы, местами, чисто вот семантически больше к месту приходятся. Это еще в пхп опущена тема виртуальных классов, в силу того, что тут все классы - априори виртуальные. Мб это и правильно, конечно, но меня немного коробит от невозможности управления оверрайдингом в потомках. А потом я оборачиваюсь на JavaScript и понимаю, что все не так и плохо.
Оу, точно. Прошляпил этот момент. Получается, вообще зеркальное отражение "классической парадигмы" виртуальных методов
Старая тема разделена на две https://php.ru/forum/threads/klassy-polimorfizm-interfejsy-final.63481/ https://php.ru/forum/threads/vyborka-ili-podschet-duplikatov.63480/