С Новым годом! Форум программистов, компьютерный форум, киберфорум
PHP
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/30: Рейтинг темы: голосов - 30, средняя оценка - 4.77
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239

Что должен вернуть метод при return $this?

05.09.2021, 21:13. Показов 6128. Ответов 40

Студворк — интернет-сервис помощи студентам
Есть метод контейнера, чтобы по 100 раз не писать имя метода при заполнении контейнера, то прописал ему return $this, в результате чего PhpStorm подсвечивает метод, мол нужно прописать ему возврат и автоматически проставляет:

PHP
1
2
3
4
5
6
7
8
9
10
public function set($id, $value): static
{
    if (array_key_exists($id, $this->results)) {
        unset($this->results[$id]);
    }
 
    $this->definitions[$id] = $value;
 
    return $this;
}
Почему :static почему не :Container?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.09.2021, 21:13
Ответы с готовыми решениями:

Можно ли через метод типа int вернуть 2 значения (return)?
Вообщем возникла такая проблема. Создал 2 метода для решения дискриминантного уравнения. Один метод сделал который ничего не возвращает, но...

Метод должен вернуть адрес ip сети
Почему не работает побитовое И? public string GetAddressOfNet() { string arr = mask.Split('.'); ...

Что return должен возвращать из функции?
простите что прошу помощи но совсем не могу понять что должен return возвращять в функциях,если кто то подскажет буду очень брагодарна ...

40
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
05.09.2021, 22:46
Лучший ответ Сообщение было отмечено DefenseMinister как решение

Решение

DefenseMinister,

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
class Container
{
    public function set($id, $value): static
    {
        if (array_key_exists($id, $this->results)) {
            unset($this->results[$id]);
        }
 
        $this->definitions[$id] = $value;
 
        return $this;
    }
}
PHP
1
2
3
4
5
6
7
class MyContainer extends Container
{
    public function test()
    {
        //...
    }
}
PHP
1
2
$myContainer =  new MyContainer();
$myContainer->set('test', 'test')->test();
Если указать возвращаемый тип Container - это тоже самое что и self
static указывает на класс текущего объекта, когда self указывает на класс в котором этот метод описан.

Короче это для наследников, так как вы возвращаете $this - это будет более точное указание типа. И это появилось в php 8, ранее нельзя было указать static в качестве возвращаемого типа.
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
05.09.2021, 23:03  [ТС]
sad67man, не ну я знаю суть static и self, но почему-то по глазам уж сильно резанула такая автоподстановка, я с неделю как 8 версию юзаю и IDE обновил раньше на 2019.3 сидел с 7.3 версией

благодарю
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 12:35
DefenseMinister, Кстати, чтоб упростить вызов, вы можете устанавливать definitions массивом, добавив метод

PHP
1
2
3
4
5
6
7
8
public function setDefinitions($definitions): static
{
    foreach ($definitions as $id => $value) {
        $this->set($id, $value);
    }
 
    return $this;
}
Добавлено через 2 часа 1 минуту
DefenseMinister, Вообще по PSR у контейнера должно быть всего 2 метода get() и has().
Вижу, что в методе set вы удаляете results[$id] - трудно представить такую ситуацию, когда вы что-то получаете из контейнера до того, как установили все definitions.

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

Т.е. вы можете сделать так

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Container
{
    private $definitions = [];
 
    public function __construct($definitions)
    {
        $this->definitions = $definitions;
    }
 
    public function get($id)
    {
        //...
    }
 
    public function has($id): bool
    {
        //...
    }
}

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ContainerBuilder
{
    private $definitions = [];
 
    public function set($id, $value): static
    {
        $this->definitions[$id] = $value;
        return $this;
    }
 
    public function build(): Container
    {
        return new Container($this->definitions);
    }
}
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$builder = (new ContainerBuilder())
    ->set('config', require __DIR__ . '/config.php')
    ->set(PDO::class, function(Container $container) {
        $config = $container->get('config')['db'];
        $this->pdo = new PDO(
            "mysql:host={$config['host']}; dbname={$config['dbname']}",
            $config['login'],
            $config['password'],
            [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
            ]
        );
    });
 
$container = $builder->build();
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 12:44  [ТС]
sad67man, у меня контейнер на минималках

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
 
namespace core;
 
use Closure;
use Error;
 
class Container
{
    private array $definitions = [];
    private array $results = [];
 
    public function set($id, $value)
    {
        if (array_key_exists($id, $this->results)) {
            unset($this->results[$id]);
        }
 
        $this->definitions[$id] = $value;
    }
 
    public function get($id)
    {
        if (array_key_exists($id, $this->results)) {
            return $this->results[$id];
        }
 
        if (array_key_exists($id, $this->definitions)) {
            $definition = $this->definitions[$id];
 
            if ($definition instanceof Closure) {
                $this->results[$id] = $definition($this);
            } else {
                $this->results[$id] = $definition;
            }
 
            return $this->results[$id];
        }
 
        throw new Error("Параметр $id не найден");
    }
}
я сотый раз попробовал использовать контейнер и сотый раз понял что он мне не нужен
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 12:54
Лучший ответ Сообщение было отмечено DefenseMinister как решение

Решение

Цитата Сообщение от DefenseMinister Посмотреть сообщение
у меня контейнер на минималках
Тогда принимайте $definitions массивом в контруктор. Собственно как я выше и привел пример. Нужен еще метод has()

И без рефлексии задолбаетесь описывать каждый класс. В контейнере описываются только те классы, которые необходимо конфигурировать. К примеру PDO, или для View необходимо указать путь к папке с вьюшками. Остальное он должен уметь создавать сам, парся через рефлексию контруктор класса и подставлять через get()

Добавлено через 5 минут
Цитата Сообщение от DefenseMinister Посмотреть сообщение
я сотый раз попробовал использовать контейнер и сотый раз понял что он мне не нужен
Контейнер внедрения зависимостей - это способ реализации принципа Inverse of Control.
Inverse of Control - это некий абстрактный принцип, набор рекомендаций для написания слабо связанного кода. Суть которого в том, что каждый компонент системы должен быть как можно более изолированным от других, не полагаясь в своей работе на детали конкретной реализации других компонентов.

Если он вам не нужен - это другое дело. Тут я бессилен)
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 13:07  [ТС]
sad67man,

у меня структура приложения не нуждается в контейнере, я в приложении создал роутер (если надо в приложении перед вызовом роутера подключить дебаггер, то создаю в App дополнительно View, чтобы пробросить в дебаггер методы для отрисовки страниц ошибок), заполняю методами роутера массив маршрутов, потом я стартую в приложении метод роутера (пробрасываю в него View, если он создавался для дебаггера), этот метод создаёт Request получает его методами из массива маршрутов нужный и создаёт объект с вызывом метода-экшена, в конструктор его мы пробрасываем View и Model, а так же передаём экшену параметром Request - это два свойства абстрактного контроллера приложения, которые нам нужны в уже созданном объекте-экшене для обращения к БД и отрисовки вида, в экшене внедрением Request мы имеем доступ к методу getBody для получения GET и POST массивов в зависимости от того каким методом получен маршрут - ВСЁ!!! Вот и вся суть приложения, мне не нужно больше ничего мудрить, я клыпаю на клыпачки помещаю или получаю данные из БД и рисую данные в видах, остальное всё моделями формируется

единственное, что я для себя открыл в контейнере, в таком, какой он у меня на минималках, так это мне не нужно для PDO создавать одиночку, потому что контейнер его закеширует в results и н там постоянно один экземпляр будет, всё что я нового и полезного извлёк из контейнера
0
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 13:22  [ТС]
sad67man, вот работает сайт на счёт раз-два

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class App
{
    private Router $router;
    private View $view;
 
    public function __construct()
    {
        $this->router = new Router();
        $this->view = new View();
    }
 
    public function getRouter(): Router
    {
        return $this->router;
    }
 
    public function debugger()
    {
        // new Debugger($this->view)
 
        // return $this;
    }
 
    public function run()
    {
        // $this->debugger->router->resolve($this->view);
        $this->router->resolve($this->view);
    }
}
 
class Router
{
    private array $routes = [];
 
    public function get(string $path, array $route): void
    {
        $this->routes['get'][$path] = $route;
    }
 
    public function post(string $path, array $route): void
    {
        $this->routes['post'][$path] = $route;
    }
 
    public function resolve(View $view)
    {
        $request = new Request();
 
        $path = $request->getPath();
        $method = $request->getMethod();
 
        if (!array_key_exists($method, $this->routes)) {
            throw new Error("Массив $method-маршрутов не найден");
        }
 
        if (!array_key_exists($path, $this->routes[$method])) {
            throw new Error("Маршрут $path в массиве $method-маршрутов не найден");
        }
 
        [$controller, $action] = $this->routes[$method][$path];
 
        if (!class_exists($controller)) {
            throw new Error("Контроллер $controller не найден");
        }
 
        if (!method_exists($controller, $action)) {
            throw new Error("Метод $controller::$action не найден");
        }
 
        $view->setView(basename(str_replace('\\', '/', $controller)));
        $view->setFile($action);
 
        call_user_func([new $controller($view), $action], $request);
    }
}
 
abstract class Controller
{
    protected View $view;
 
    public function __construct(View $view)
    {
        $this->view = $view;
    }
}
 
class Home extends Controller
{
    public function index(/*Request $request если нужен метод getBody()*/)
    {
        echo __METHOD__;
        
        $this->view->render();
    }
}
Миниатюры
Что должен вернуть метод при return $this?  
0
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 13:34  [ТС]
sad67man, а вообще это всё можно сделать так

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class App
{
    public function __construct()
    {
        // создаём нужные нам объекты, типа контейнер тут у нас
    }
 
    public function run()
    {
        $this->router->resolve($this);
    }
}
 
class Router
{
    // код
 
    public function resolve(App $app)
    {
        // код
 
        new $controller($app); что-то вроде этого
    }
}
 
abstract class Controller
{
    protected App $app;
 
    public function __construct(App $app)
    {
        $this->app= $app; // всё что душа пожелает :)
    }
}
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 14:20
Лучший ответ Сообщение было отмечено DefenseMinister как решение

Решение

DefenseMinister, Да я уже кое-что описал по этой архитектуре Декоратор или свойство?

Цитата Сообщение от DefenseMinister Посмотреть сообщение
public function resolve(View $view)
Вот у вас тут получается, что чтоб создать контроллер вы прокидываете View в роутер, хотя еще не факт что он понадобится в контроллере. Получается вы обременяете роутер знаниями - как именно создавать контроллер и какие у него зависимости. Вместо этого вы бы могли вынести создание контроллера в отдельны класс

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Resolver
{
    private $container;
 
    public function __construct(Container $container)
    {
        $this->container = $container;
    }
 
    public function resolve($handler, Request $request): Response
    {
        if (is_array($handler)) {
            $controllerName = $handler[0] ?? null;
            $action = $handler[1] ?? null;
            if (!class_exists($controllerName)) {
                throw new Error("Контроллер $controllerName не найден");
            }
 
            if (!method_exists($controllerName, $action)) {
                throw new Error("Метод $controllerName::$action не найден");
            }
            
            $controller = $this->container->get($controllerName);
 
            return $controller->{$handler[1]}($request);
        }
 
        if ($handler instanceof \Closure) {
            return $handler($request);
        }
 
        throw new Exception();
    }
}
В момент написания класса мы не задумываемся о том, в каком месте он будет вызываться и каким образом мы будем интегрировать его в нашу систему. Мы можем его просто подключить, допустим в тот же самый роутер

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Router
{
    private array $routes = [];
    /**
     * @var Resolver
     */
    private $resolver;
 
    public function __construct(Resolver $resolver)
    {
        $this->resolver = $resolver;
    }
 
    public function resolve(Request $request)
    {
        $path = $request->getPath();
        $method = $request->getMethod();
 
        if (!array_key_exists($method, $this->routes)) {
            throw new Error("Массив $method-маршрутов не найден");
        }
 
        if (!array_key_exists($path, $this->routes[$method])) {
            throw new Error("Маршрут $path в массиве $method-маршрутов не найден");
        }
 
        [$controller, $action] = $this->routes[$method][$path];
 
        return $this->resolver->resolve([$controller, $action], $request);
    }
}
И в вашей теме я указывал, что у контроллера могут быть разные зависимости, возможно view ему и вовсе не понадобится.

Добавлено через 4 минуты
Цитата Сообщение от DefenseMinister Посмотреть сообщение
а вообще это всё можно сделать так
Вот так точно лучше не делать) Это все равно, что сделать $app доступным глобально. И дергать из любого места.

Добавлено через 1 минуту
DefenseMinister, В данном случае нужно понимать, что Resolver единственный, кто получает Контейнер в качестве зависимости, ровно для того, чтоб создать контроллер. Все остальные классы не должны знать о его существовании.

Добавлено через 13 минут
DefenseMinister, Контроллер может тогда выглядеть таким образом

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class BlogController
{
    private $view;
    private $presentator;
 
    public function __construct(
        View $view,
        PostsPresentator $presentator
    )
    {
        $this->view = $view;
        $this->presentator = $presentator;
    }
 
    public function posts(Request $request): Response
    {
        $page = $request->page ?? 1;
        $data = $this->presentator->getList($page);
 
        return new HtmlResponse(
            $this->view->render('blog/posts', $data)
        );
    }
}
DI Контейнер позволяет выносить отдельные куски кода по классам, у которых могут быть свои зависимости и с легкостью их подключать в конструктор. Особенно это удобно при выполнения какой-либо довольно сложной операции бизнес логики. Где можно выкинуть исключение из любой вложенности вызываемых методов. А такая вложенность может быть довольно большая.
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 14:32  [ТС]
sad67man, надо будет потестить руками погонять такой подход на прочтение не полностью доходит что куда летит

кстати вот эта проверка меня смущает

PHP
1
2
3
4
5
6
7
if (!class_exists($controllerName)) {
    throw new Error("Контроллер $controllerName не найден");
}
 
if (!method_exists($controllerName, $action)) {
    throw new Error("Метод $controllerName::$action не найден");
}
я тоже так проверяю , НО, если в классе нет такого метода, А в конструкторе что-то вроде проверки с отлупом, то мы получается нарываемся на МЕТОД НЕ НАЙДЕН, в то время как класс его и не собирается вызывать, пока не отработал конструктор

может быть правильно проверять метод уже из объекта?

PHP
1
2
3
4
5
6
7
8
9
if (!class_exists($controllerName)) {
    throw new Error("Контроллер $controllerName не найден");
}
 
$controller = new $controllerName; // тут сработает сначала какой-то код конструктора, если он есть
 
if (!method_exists($controller, $action)) {
    throw new Error("Метод $controllerName::$action не найден");
}
?

Добавлено через 6 минут
Цитата Сообщение от sad67man Посмотреть сообщение
нужно понимать, что Resolver единственный
вот на таких моментах и начинается: - Что? Ещё один класс создавать? Зачем, если работает и без него? Два класса создают объект, вместо одного метода?

ну и так далее...

Добавлено через 54 секунды
в итоге понасоздавали классов и получили Hello World
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 14:42
Цитата Сообщение от DefenseMinister Посмотреть сообщение
кстати вот эта проверка меня смущает
Это и есть ваш код) Я просто его перенес в Resolver, который только что накидал под ваш код) Вы должны понимать, что я показываю схематически.

А так вы правы - лучше создать сначала контроллер

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Resolver
{
    private $container;
 
    public function __construct(Container $container)
    {
        $this->container = $container;
    }
 
    public function resolve($handler, Request $request): Response
    {
        if (is_array($handler)) {
            $controllerName = $handler[0] ?? null;
            $action = $handler[1] ?? null;
            if (!class_exists($controllerName)) {
                throw new Error("Контроллер $controllerName не найден");
            }
 
            $controller = $this->container->get($controllerName);
 
            if (!method_exists($controller, $action)) {
                throw new Error("Метод $controllerName::$action не найден");
            }
 
            return $controller->{$action}($request);
        }
 
        if ($handler instanceof \Closure) {
            return $handler($request);
        }
 
        throw new Exception();
    }
}
Добавлено через 7 минут
DefenseMinister, Вам следует переступить этот порог боязни создать лишний класс. Не бойтесь создавать классы. Их можно писать столько сколько потребуется. Тем более, что в PhpStorm-e это секундное дело. В данном случае мы вынесли в отдельный класс, потому что сам контейнер роутеру не нужен. Это разделение по ответственностям. Более того вы можете его повторно использовать к примеру.

PHP
1
2
3
4
5
6
7
8
public function handle(Request $request)
{
    try {
        return $this->router->resolve($request);
    } catch (NotFoundException $e) {
        return $this->resolver->resolve([ErrorController::class, 'error'], $request);
    }
}
Опять же учтите, что пример я только что выдумал. Просто для демонстрации, что разделение классов по ответственностям открывают дополнительные возможности. Никогда не знаешь, когда они смогут пригодиться. Когда появляется такая необходимость появляется, а у вас уже все разделено - просто с этим приятно работать)
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 14:49  [ТС]
sad67man,

смотри в Resolver прилетает Container и потом Resolver улетает в Router, ну так с таким же успехом я могу Container отправить в Router и достать из него всё что надо там, а не из резольвера, который это же достает из него

я не пойму почему из контейнера я должен по капле что-то выбирать если у меня есть контейнер ЗАВИСИМОСТЕЙ, если это зависимости моего приложения, то почему я не могу к ним иметь доступ в любом месте ТУПО ПЕРЕДАВАЯ контейнер из класса в класс )))

то что ты мне постоянно пишешь о том что один класс не должен знать о существовании другого - нарушает моё представление о контейнере

нахера нам контейнер зависимостей если мы изолируем классы друг от друга?

и почему нужно мучить жопу не передав контейнер и достав оттуда всё что нужно, а должны передать только то что нужно

ведь в контейнере и так всё уже создаётся и хранится, какая разница хранить всё и дёргать одно или дергать одно при том что всё уже и так хранится, нахера мне куча параметров при передаче, если я могу одним параметром передать контейнер УЖЕ СОЗДАННЫЙ ничего там лишнего нет, там то же самое в нём, что и при передаче одного параметра из контейнера, он такой же контейнер он не разрастается и не уменьшается при передаче всего контейнера)))

)))
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 14:54
Цитата Сообщение от DefenseMinister Посмотреть сообщение
надо будет потестить руками погонять такой подход на прочтение не полностью доходит что куда летит
Чтоб эта вся магия работала необходимо доработать контейнер, подключив рефлексию

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Container
{
    private array $definitions = [];
    private array $results = [];
    
    public function __construct($definitions)
    {
        $this->definitions = $definitions;
    }
 
    public function get($id)
    {
        if (array_key_exists($id, $this->results)) {
            return $this->results[$id];
        }
 
        if (array_key_exists($id, $this->definitions)) {
            $definition = $this->definitions[$id];
 
            if ($definition instanceof Closure) {
                $this->results[$id] = $definition($this);
            } else {
                $this->results[$id] = $definition;
            }
 
            return $this->results[$id];
        }
 
        if (class_exists($id)) {
            $reflection = new ReflectionClass($id);
            $construct = $reflection->getConstructor();
            $params = [];
            foreach ($construct->getParameters() as $parameter) {
                $params[] = $this->get($parameter->getClass()->getName());
            }
            $this->results[$id] = $reflection->newInstanceArgs($params);
        }
        
 
        throw new Error("Параметр $id не найден");
    }
}
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 14:59  [ТС]
sad67man, а ну теперь вроде понял, автоматом будут залетать те зависимости, которые параметрами указаны в классе, дошло вроде
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 15:05
Цитата Сообщение от DefenseMinister Посмотреть сообщение
я не пойму почему из контейнера я должен по капле что-то выбирать если у меня есть контейнер ЗАВИСИМОСТЕЙ
Поправочка - "контейнер ВНЕДРЕНИЯ зависимостей". Т.е. вы все зависимости просто указываете в конструкторе. А контейнер их туда подставляет. Т.е. вся магия происходит снаружи класса, а не внутри.

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

По сути если прокидывать сам контейнер во все классы, то это равнозначно тому, если вы будете использовать те же антипатерны синглтоны с методами getInstance().

Если рассматривать класс снаружи, когда все что находится внутри для нас черный ящик. То мы видим, что он принимает в контруктор целый контейнер - и это не несет никакой информации, и мне становится страшно, что он там может из него дергать все что угодно.
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 15:08  [ТС]
Цитата Сообщение от sad67man Посмотреть сообщение
синглтоны с методами getInstance()
не ну от одиночки мы избавляемся кешированием в results как бы

я про магию с рефлексией догнал короче
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 15:17
Цитата Сообщение от DefenseMinister Посмотреть сообщение
не ну от одиночки мы избавляемся кешированием в results как бы
Да это тоже по сути singlton, только более гибкий.

Еще контейнер служит, чтоб сопоставлять интерфейсы. К примеру

PHP
1
2
3
4
5
interface StotrageInterface
{
    public function load(): CartItemsCollection;
    public function save(CartItemsCollection $items): void;
}
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Cart
{
    private $storage;
 
    public function __construct(StotrageInterface $storage)
    {
        $this->storage = $storage;
    }
 
    public function add(CartItem $cartItem): void
    {
        $items = $this->storage->load();
        $items->add($cartItem);
        $this->storage->save($items);
    }
}
Далее мы можем реализовать к примеру SessionStorage и указать в контейнере

PHP
1
2
3
$container = new Container([
    StotrageInterface::class => SessionStorage::class
]);
И корзина будет работать на сессиях. Если нужно будет переделать на БД, то реализуете другой класс

PHP
1
2
3
$container = new Container([
    StotrageInterface::class => DbStorage::class
]);
И корзина уже будет работать на базе данных. Таким образом мы абстрагируемся от реализации и может подставлять любую, какая больше подойдет и т.д.
1
-9 / 8 / 3
Регистрация: 17.02.2021
Сообщений: 239
06.09.2021, 17:15  [ТС]
sad67man, контейнер мне так собирать?

PHP
1
2
3
4
5
6
7
8
9
10
11
class Container
{
    private array $definitions;
 
    public function __construct()
    {
        $configuration = array_map(fn($file) => require $file, glob(D_R . 'configuration' . D_S . '*.php'));
 
        $this->definitions = array_merge_recursive(...$configuration);
    }
}
или собрать нужно вне и прислать ИМЕННО параметром массив?
0
 Аватар для sad67man
2603 / 1507 / 689
Регистрация: 23.08.2015
Сообщений: 3,815
06.09.2021, 17:30
DefenseMinister, Нет лучше это делать снаружи класса.

PHP
1
2
3
4
5
6
class Container
{
    public function __construct(
        private array $definitions = []; // фишка php8 кстати как раз для более удобного подключения зависимостей)
    ) {}
}
PHP
1
2
3
//файл container.php
$configuration = array_map(fn($file) => require $file, glob(__DIR__ . '/definitions/*.php'));
return new Container(array_merge_recursive(...$configuration));

PHP
1
2
3
4
//public/index.php
 
$container = requre dirname(__DIR__) . '/config/container.php';
$app = $container->get(Application::class);
Добавлено через 4 минуты
DefenseMinister, Есть библиотека для более умного смерживания конфигов.
https://github.com/zendframewo... aggregator
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.09.2021, 17:30
Помогаю со студенческими работами здесь

Что значит вернуть объект? return
const Stock&amp; Stock::topval(const Stock&amp; s) const { if (s.totalVal &gt; totalVal) // если totalVal больше totalVal объекта который вызвал...

Метод класса должен вернуть этот класс
Вообщем есть класс и его метод. Как изменить этот метод, чтобы при использовании возвращался этот класс с новыми данными Для примера...

Метод который должен вернуть коллекции <элемент массива,частота>
работает некорректно public static Dictionary&lt;double,int&gt; di= new Dictionary&lt;double, int&gt;(); static public...

WCF метод должен вернуть приемлемый тип для dataGridView
Я не знаю как правильно оформить метод, чтобы он возвращал правильный тип, который на принимающей стороне можно было записать как ...

Рекурсия: верно ли, что return result должен сработать n-1 раз?
верно ли, что return result должен сработать n-1 раз? using System; class Factorial { // Рекурсивный метод, public int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru