• Чем array_walk лучше foreach?

    @novrm
    Работая по ссылке с foreach можете налететь на очень неприятны грабли, которые незаметны и сильно попортят вам нервы.
    Особенно когда разработчики неопытные.
    И именно - ссылку после foreach нужно удалять.
    array_walk для работы по ссылке - само-то, лишь тем и лучше.
    В других случаях — будь попроще — используй foreach.

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

    Пример:
    array_walk($guide['postInGuides'], function (&$postInGuide, $key) use ($guide, $viewRenderer) {
        $postInGuide['post']['url'] = [
            'read' => $viewRenderer->url('guide/guide/post', [
                'slugGuide' => $guide['name'],
                'slugPost'  => $postInGuide['post']['slug'],
            ]),
            'update' => $viewRenderer->url('post/post/action', [
                'slugPost'  => $postInGuide['post']['slug'],
                'action' => 'update',
            ]),
            'delete' => $viewRenderer->url('post/post/action', [
                'slugPost'  => $postInGuide['post']['slug'],
                'action' => 'delete',
            ]),
        ];
    });
    Ответ написан
    Комментировать
  • Какой фреймворк выбрать для обучения?

    @novrm
    Представьте, что вы пришли в большую университетскую библиотеку и говорите: "Я желаю в кратчайшие сроки стать самым-самым главным библиотекарем это библиотеки, Желаю знать структуру библиотеки, разделы, все книги, все книги по разделам, ориентироваться во всех авторах, их деятельности, жанрах... А также знать всех читателей, их нравы, повадки и приоритеты... Также нужно мне обладать информацией об связях библиотеки с другими учреждениями, быть в курсе лекций, симпозиумов, конференций"...
    И все это в кратчайшие сроки ибо время поджимает.
    Понимаете ли вы тогда, что некоторые люди к этому идут не один год?

    Теперь по существу.
    Symfony - самый тяжелый в изучении, и рекомендовать его начинающему я бы не стал.
    Zend Framework - тот же Symfony но с меньшим набором "плюшек" и меньшим сообществом. Порог вхождения - легче.
    Lavarel, Yii - легкое вхождение за счет уже готового кода, что сыграет с вами потом плохую шутку. Ибо любой framework по замыслу программистов - это минимальный скелет, на который вам нужно самостоятельно наращивать мышцы...

    Еще короче - выбирая framework вы оказываетесь в ситуации дистрофика, которому нужно выиграть на конкурсе Мистер Юниверс.

    Спросите сто раз нужно ли вам это.
    Ответ написан
    Комментировать
  • Как быть с контроллером?

    @novrm
    Значит так - пиши такой маршрут.
    А об пагинаторе я тебе отписал дальше.
    'router' => [
        'routes' => [
    
            /** Configuration of the 'shop' routes. */
            'shop' => [
                'type'    => 'Literal',
                'options' => [
                    'route'    => '/shop/',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
                'may_terminate' => true,
                'child_routes' => [
    
                    /** Configuration of the 'shop/category' routes. */
                    'category' => [
                        'type'    => 'Literal',
                        'options' => [
                            'route'    => 'category/',
                            'defaults' => [
                                'controller' => Controller\CategoryController::class,
                                'action'     => 'index',
                            ],
                        ],
                        'may_terminate' => true,
                        'child_routes' => [
    
                            /** Configuration of the 'shop/category/action' routes. */
                            'action' => [
                                'type' => 'Segment',
                                'options' => [
                                    'route' => '[:action]',
                                    'constraints' => [
                                        'action' => '(create)',
                                    ],
                                ],
                            ],
    
                            /** Configuration of the 'shop/category/category' routes. */
                            'category' => [
                                'type' => 'Segment',
                                'options' => [
                                    'route' => '[:id/]',
                                    'constraints' => [
                                        'id' => '[0-9]+',
                                    ],
                                    'defaults' => [
                                        'id' => null,
                                    ],
                                ],
                                'may_terminate' => true,
                                'child_routes' => [
    
                                    /** Configuration of the 'shop/category/category/action' routes. */
                                    'action' => [
                                        'type' => 'Segment',
                                        'options' => [
                                            'route' => '[:action]',
                                            'constraints' => [
                                                'action' => '(update|delete)',
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
    Ответ написан
  • Как вытащить id в phtml?

    @novrm
    Не понял юмора. Просто передай в вид переменную id.
    Не нужно ее пихать в пагинатор и пытаться оттуда достать недоставуемое.

    Пагинатор в вид отдает только следующие переменные, и не больше.
    .---------------------------------------------------------------------------------------.
     | Property         | Type    | Description                                              |
     |---------------------------------------------------------------------------------------|
     | first            | integer | First page number (typically 1).                         |
     | firstItemNumber  | integer | Absolute number of the first item on this page.          |
     | firstPageInRange | integer | First page in the range returned by the scrolling style. |
     | current          | integer | Current page number.                                     |
     | currentItemCount | integer | Number of items on this page.                            |
     | itemCountPerPage | integer | Maximum number of items available to each page.          |
     | last             | integer | Last page number.                                        |
     | lastItemNumber   | integer | Absolute number of the last item on this page.           |
     | lastPageInRange  | integer | Last page in the range returned by the scrolling style.  |
     | next             | integer | Next page number.                                        |
     | pageCount        | integer | Number of pages.                                         |
     | pagesInRange     | array   | Array of pages returned by the scrolling style.          |
     | previous         | integer | Previous page number.                                    |
     | totalItemCount   | integer | Total number of items.                                   |
     '---------------------------------------------------------------------------------------'
    Ответ написан
    Комментировать
  • Пишет Class not found. Как правильно определить пространство имен?

    @novrm
    Было так:
    $test = new app\Pi\test;
    Попробуйте вот так:
    $test = new \app\Pi\test;
    А вообще-то Все нужно делать из Заглавной. Вот так:
    $test = new \App\Pi\Test();
    Ответ написан
    Комментировать
  • PHP. Возможно ли сократить следующий код?

    @novrm
    <?= isset($_GET['e']) ? $_GET['e'] : (isset($_POST['email']) ? $_POST['email'] : (isset($_COOKIE['e']) ? $_COOKIE['e'] : null)) ?>

    или для "продуктивности" (дважды не извлекать переменную):
    <?= isset($getE = $_GET['e']) ? $getE : (isset($postEmail = $_POST['email']) ? $postEmail : (isset($cookieE = $_COOKIE['e']) ? $cookieE : null)) ?>
    Ответ написан
    Комментировать
  • Как изменить config.php посредством php?

    @novrm
    Неизвестно как вы строите админку - с ООП или без ООП.

    В вашем случае config представляет собой ассоциативный массив, значит нужны инструменты для этого.
    Например: Стандартная библиотека PHP (SPL).
    На основе это нужно городить классы для проверки обновления и добавления записей в массив...
    Как вы понимаете - это ваш велосипед, имитирующий работу с базой данных...

    В любом случае - конфигурация предназначена для глобальных настроек модуля или чего-то...
    Настройки отдельного пользователя лучше хранить в базе данных - для чего, собственно, это и придумано.
    Ответ написан
    Комментировать
  • Как использовать autoload.php из composer?

    @novrm
    Взято из Composer Cheat Sheet for developers.
    Вот вам более расширенный пример:
    "autoload": {
            "psr-4": {
                "Application\\": "module/Application/src/",
                "Vendor\\Namespace\\": ""
            },
            "psr-0": {
                "Monolog": "src/",
                "Vendor\\Namespace": ["src/", "lib/"],
                "Pear_Style": "src/",
                "": "src/"
            },
            "classmap": ["src/", "lib/", "Something.php"],
            "files": ["src/MyLibrary/functions.php"]
        },

    Кроме того, дабы обновлять эти зависимости при установке новых модулей, в composer.json нужно или прописать:
    "config": {
            "optimize-autoloader": true
        },

    или вручную вызывать команду для composer:
    $ php composer.phar dump-autoload --optimize
    Ответ написан
    2 комментария
  • Где найти готовые шаблоны баз данных?

    @novrm
    Существуют разные строения баз данных.
    Если речь идет об реляционных БД - забудь об древовидном строении... После этого приходит понимание связи между двумя таблицами - посредством третьей...
    Это понимание самое важное.
    Ответ написан
  • Как создать связанные записи со связью many-to-many в zend framework, используя doctrine?

    @novrm
    Если поможет, если не поможет - звиняйте...
    Попробуйте вот эти инструменты:
    https://www.mysql.com/products/workbench/
    https://github.com/mysql-workbench-schema-exporter...

    На скорую руку автомат наваял следующие сущности для пробного модуля TestModule:
    b52390696a37424bb2aafa429bc25bf1.jpg
    <?php
    
    /**
     * Auto generated by MySQL Workbench Schema Exporter.
     * Version 3.0.2 (doctrine2-annotation) on 2016-07-26 19:31:50.
     * Goto https://github.com/johmue/mysql-workbench-schema-exporter for more
     * information.
     */
    
    namespace TestModule\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\Common\Collections\ArrayCollection;
    
    /**
     * TestModule\Entity\Portfolio
     *
     * @ORM\Entity()
     * @ORM\Table(name="Portfolio")
     * @ORM\InheritanceType("SINGLE_TABLE")
     * @ORM\DiscriminatorColumn(name="discr", type="string")
     * @ORM\DiscriminatorMap({"base":"BasePortfolio", "extended":"Portfolio"})
     */
    class BasePortfolio
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         */
        protected $idPortfolio;
    
        /**
         * @ORM\ManyToMany(targetEntity="Tag", mappedBy="portfolios")
         */
        protected $tags;
    
        public function __construct()
        {
            $this->tags = new ArrayCollection();
        }
    
        /**
         * Set the value of idPortfolio.
         *
         * @param integer $idPortfolio
         * @return \TestModule\Entity\Portfolio
         */
        public function setIdPortfolio($idPortfolio)
        {
            $this->idPortfolio = $idPortfolio;
    
            return $this;
        }
    
        /**
         * Get the value of idPortfolio.
         *
         * @return integer
         */
        public function getIdPortfolio()
        {
            return $this->idPortfolio;
        }
    
        /**
         * Add Tag entity to collection.
         *
         * @param \TestModule\Entity\Tag $tag
         * @return \TestModule\Entity\Portfolio
         */
        public function addTag(Tag $tag)
        {
            $this->tags[] = $tag;
    
            return $this;
        }
    
        /**
         * Remove Tag entity from collection.
         *
         * @param \TestModule\Entity\Tag $tag
         * @return \TestModule\Entity\Portfolio
         */
        public function removeTag(Tag $tag)
        {
            $this->tags->removeElement($tag);
    
            return $this;
        }
    
        /**
         * Get Tag entity collection.
         *
         * @return \Doctrine\Common\Collections\Collection
         */
        public function getTags()
        {
            return $this->tags;
        }
    
    }


    <?php
    
    /**
     * Auto generated by MySQL Workbench Schema Exporter.
     * Version 3.0.2 (doctrine2-annotation) on 2016-07-26 19:31:50.
     * Goto https://github.com/johmue/mysql-workbench-schema-exporter for more
     * information.
     */
    
    namespace TestModule\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\Common\Collections\ArrayCollection;
    
    /**
     * TestModule\Entity\Tag
     *
     * @ORM\Entity()
     * @ORM\Table(name="Tag")
     * @ORM\InheritanceType("SINGLE_TABLE")
     * @ORM\DiscriminatorColumn(name="discr", type="string")
     * @ORM\DiscriminatorMap({"base":"BaseTag", "extended":"Tag"})
     */
    class BaseTag
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         */
        protected $idTag;
    
        /**
         * @ORM\ManyToMany(targetEntity="Portfolio", inversedBy="tags")
         * @ORM\JoinTable(name="Portfolio_has_Tag",
         *     joinColumns={@ORM\JoinColumn(name="Tag_idTag", referencedColumnName="idTag", nullable=false)},
         *     inverseJoinColumns={@ORM\JoinColumn(name="Portfolio_idPortfolio", referencedColumnName="idPortfolio", nullable=false)}
         * )
         */
        protected $portfolios;
    
        public function __construct()
        {
            $this->portfolios = new ArrayCollection();
        }
    
        /**
         * Set the value of idTag.
         *
         * @param integer $idTag
         * @return \TestModule\Entity\Tag
         */
        public function setIdTag($idTag)
        {
            $this->idTag = $idTag;
    
            return $this;
        }
    
        /**
         * Get the value of idTag.
         *
         * @return integer
         */
        public function getIdTag()
        {
            return $this->idTag;
        }
    
        /**
         * Add Portfolio entity to collection.
         *
         * @param \TestModule\Entity\Portfolio $portfolio
         * @return \TestModule\Entity\Tag
         */
        public function addPortfolio(Portfolio $portfolio)
        {
            $portfolio->addTag($this);
            $this->portfolios[] = $portfolio;
    
            return $this;
        }
    
        /**
         * Remove Portfolio entity from collection.
         *
         * @param \TestModule\Entity\Portfolio $portfolio
         * @return \TestModule\Entity\Tag
         */
        public function removePortfolio(Portfolio $portfolio)
        {
            $portfolio->removeTag($this);
            $this->portfolios->removeElement($portfolio);
    
            return $this;
        }
    
        /**
         * Get Portfolio entity collection.
         *
         * @return \Doctrine\Common\Collections\Collection
         */
        public function getPortfolios()
        {
            return $this->portfolios;
        }
    
    }
    Ответ написан
    Комментировать
  • Как вывести многомерный массив каталогов их содержимого через PHP?

    @novrm
    Вы напишите код - я мы обсудим и поможем...
    Ответ написан
    Комментировать
  • Как правильно добавлять множество полей в БД?

    @novrm
    Читайте про ORM.
    Один класс - одна ответственность.
    В двух словах - один класс (class Entity) - для данных, в котором поля класса соответствуют полям таблицы из базы данных, а методы - сеттеры и геттеры - устанавливают и возвращают значение этих полей...
    Второй класс (class Mapper) - исключительно для заполнения Entity данными из базы данных (выборка)...
    Кроме того отдельные классы для установления связи с базой данных, установка ее параметров и прочее...
    Вобщем - получите PDO, Doctrine,...
    Ответ написан
    Комментировать
  • Как правильно подключить MySQli в отдельном файле?

    @novrm
    Используйте PDO.
    Ответ написан
    Комментировать
  • Как спроектировать классы?

    @novrm
    Если первое - вывод инфы в шаблон - несомненно переходите на twig.
    Когда вы начнете юзать twig - приятно удивитесь насколько легкий порог вхождения...

    Для работы с базой данных попробуйте - Doctrine 2 Object Relational Mapper (ORM).
    Если будете пилять что-то свое - используйте Объектно Реляционное Отображение.

    Если захотите все сразу и больше: twig, ORM, ООП все в одном - возьмите на вооружение какой-то фреймворк - например Zend Framework или Symfony.
    Ответ написан
  • Модульная система на PHP, как защитить?

    @novrm
    Может не совсем понял - но вы пишите свой велосипед-фреймворк...
    Чем вам не угодили, например, Zend или Symfony?

    Да - еще - используйте принцип: - один класс - один файл - единственная ответственность.
    А то, как я понимаю, ваш класс-модуль будет и подключать другие модули и с базой данных работать и какие-то еще другие функции выполнять... Это дорога в пекло...
    Ответ написан
    Комментировать