LINUX.ORG.RU

Любые нормальные фреймворки предоставляют эту возможность.

Yii/Symfony точно дают. А точно ли нужен именно пых? Может стоит присмотреться к альтернативам

nihirash ★★★
()

Я в свое время запиливал так, что при вызове точки входа оно автоматом тянет обычные контроллеры но в режиме CLI, тип того:

$ php /path/do/index.php /foo/bar?a=1&b=2 --post c=3&d=4

а в коде все просто:

if ('cli' === PHP_SAPI) {
    // мы в CLI
} else {
    // пришло от сервера (CGI/mod)
}

Ну аргументы сам распарсишь, там не сложно.

deep-purple ★★★★★
()

консольные фреймворки PHP с ORM, которые работают в консольных скриптах, без веб-сервера?

Просто накати doctrine и pimple через composer.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Каким образом можно запустить симфонию в консоле? Я делаю так

simfony/vendor/autoload.php

Далее хочу загрузить в Entity данные из базы
$em->getRepository('AppBundle:Product')->find($productId);

Но $em(EntityManager) откуда взять? В примерах его берут в контролерах, а откуда контролеры в консоле?

gobot ★★★★
() автор топика

О боже «Personal Home Page Tools» в консоли ? Закопайте

Jopich1
()
Ответ на: комментарий от nihirash

Как раз есть сайт на симфонии, хочу интегрировать его с консольным скриптом, но не получается

gobot ★★★★
() автор топика
Ответ на: комментарий от Noob_Linux

Я это делал, но не понимаю как загрузить Entity из БД. В примерах везде используют EntityManager, но как до него добраться не пойму. примеры смотрел тут http://symfony.com/doc/current/doctrine.html

$em->getRepository('AppBundle:Product')->find($productId);

gobot ★★★★
() автор топика
Ответ на: комментарий от Noob_Linux

Такой пример я видел, но $this в каком контексте?
Вот мой код

require "/path/to/symfony/vendor/autoload.php";
use AppBundle\Entity\Server;
use Symfony\Component\Console\Application;
$app = new Application();
$app->run();

Мне тупо нужно создать Entity и загрузить в него данные из БД

gobot ★★★★
() автор топика
Ответ на: комментарий от Noob_Linux

Это какая то команда создалась... я как понимаю ее ещё запускать нужно, короче бред полный, все это не то. Мне нужно дергать из любого места моего консольного скрипта классы логики(которые лежат в AppBundle), которые общие между сайтом и консольными скриптами, но что толку их дергать, если тупо нет доступа к базе даже

require "/vendor/autoload.php";

class CreateUserCommand extends \Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand
{
    // ...
    
    protected function configure()
    {
        $this            
            ->setName('app:create-user')            
            ->setDescription('Creates a new user.')
            ->setHelp('This command allows you to create a user...')
        ;
    }    

    protected function execute()
    {
        $doctrine = $this->getContainer()->get('doctrine');
        var_dump($doctrine);
    }
}


new CreateUserCommand()

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Так и работой в execute, что мешает? Вообще надо это создавать в контексте AppBundle и не создавать непонятно где еще один файл где все делать непонятно как.

Noob_Linux ★★★★
()
Последнее исправление: Noob_Linux (всего исправлений: 1)
Ответ на: комментарий от Noob_Linux

Ну мне кажется это костыль какой то. Создавать какую то команду, потом ее запускать. Как правильней сделать то? У меня ещё там \React\EventLoop будет

Да и вообще не запускается даже так

require "/vendor/autoload.php";

class CreateUserCommand extends \Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand
{
    // ...
    
    protected function configure()
    {
        $this            
            ->setName('app:create-user')            
            ->setDescription('Creates a new user.')
            ->setHelp('This command allows you to create a user...')
        ;
    }    

    protected function execute()
    {
        $doctrine = $this->getContainer()->get('doctrine');
        var_dump($doctrine);
    }
}


$app = new Application();
$app->add(new CreateUserCommand());
$app->run();

PHP Fatal error:  PHP Fatal error:  Call to undefined method Symfony\Component\Console\Application::getKernel() 

Запускаю все это так
php daemon.php app:create-user

gobot ★★★★
() автор топика
Последнее исправление: gobot (всего исправлений: 1)
Ответ на: комментарий от gobot

Ну мне кажется это костыль какой то. Создавать какую то команду, потом ее запускать.

Это правильный путь если ты хочешь работать в контексте всего остального кода написанного на Symfony (и не только). Тебе это кажется костылем лишь из-за отсутствия опыта.

Как правильней сделать то?

1.Идешь в папочку src/AppBundle/Command

2. Создаешь класс для своей команды как это делал ранее (просто класс, ничего более не надо)

3. В нем реализовываешь всю логику необходимую для работы команды

4. php bin/console my-command (в корне проекта естественно)

5. профит

Noob_Linux ★★★★
()
Последнее исправление: Noob_Linux (всего исправлений: 2)
Ответ на: комментарий от Noob_Linux

Понятно, спасибо, попробую сделать так. Вообще я думал, что симфонию прикручу к скрипту консольному, а получается нужно наоборот делать, симфония будет запускать, все инициировать

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

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

Noob_Linux ★★★★
()
Ответ на: комментарий от Noob_Linux

Кстати забыл сказать, скрипт у меня будет работать беспрерывно в режиме ожидания, ну типа демона, для этого я \React\EventLoop использую. Такое будет в симфонии работать?

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Далее хочу загрузить в Entity данные из базы

Хм. Интересно. А у меня объекты сами себя грузят (точнее, инжектнутыми драйверами бэкенда):

$product = \App\Product::load($product_id);


или

foreach(\App\Product::find()->in('product_id', $ids)->all() as $prod
{
    // ...
}


Интересно, это чем-то может быть чревато кроме не совсем кристально чистого MVC? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от gobot

В примерах его берут в контролерах, а откуда контролеры в консоле?

Ну вообще-то там и должны быть консольные контроллеры. Но вообще взять можно из DI-контейнера, он же ServiceContainer в терминологии symfony. Гляди https://symfony.com/doc/current/service_container.html там прям в качестве примера достают em.

Ну а если тебе контроллеры (т.е. роуты) не нужны, то как я тебе советовал просто накати доктрину через композер и всё. Скаффолдинг и прочие плюшки у доктрины есть свои.

Т.е. в целом сейчас подход такой - композер это и есть фреймворк, накатываем компоненты по вкусу.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от KRoN73

чем-то может быть чревато кроме не совсем кристально чистого MVC?

Интересно, а откуда в entity взялся find? Он же должен быть в классе-репозитории.

no-such-file ★★★★★
()
Ответ на: комментарий от KRoN73

Вот этого я тоже хотел добиться с самой первой минуты изучения симфонии )) Потому что это же дурость, что сам Entity не может самого себя загрузить, вместо того что бы делать

\App\Product::load($id)


В доках везде примеры, что нужно сначала какой то EntityManager взять, потом репозитарий, оттуда сделать выборку. Причем $em ещё так неявно получить можно

$em->getRepository('AppBundle:Product')->find($productId);

Скажи как тебе удалось сделать автозагрузку, через injectObjectManager?

gobot ★★★★
() автор топика
Ответ на: комментарий от no-such-file

Так симфония и устанавливается через коспозер, там же есть и доктрина. Но мне то нужно, чтобы было все единый проект, классы то едины что для веба, что для консольного скрипта.
В корне проекта лежит composer.json

 
...
    "require": {
        "php": ">=5.5.9",
        "doctrine/doctrine-bundle": "^1.6",
        "doctrine/orm": "^2.5",
        "incenteev/composer-parameter-handler": "^2.0",
        "sensio/distribution-bundle": "^5.0.19",
        "sensio/framework-extra-bundle": "^3.0.2",
        "symfony/assetic-bundle": "^2.8",
        "symfony/monolog-bundle": "^3.1.0",
        "symfony/polyfill-apcu": "^1.0",
        "symfony/swiftmailer-bundle": "^2.3.10",
        "symfony/symfony": "3.3.*",
        "twig/twig": "^1.0||^2.0"
    }

...

Я хочу, чтобы классы сами в себя загружали данные из БД, т.е. про EntityManager и прочие специфичные вещи фреймворка я не хочу знать, все должно абстрагироваться в самих классах. Т.е. консольный скрипт берет только часть «бизнес-логики», которая находиться в фреймворке, а сам не должен знать о существовании его(фреймворка). Ну или как сделать то? Нужны разделяемые классы, которые можно использовать где угодно

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Вообще я думал, что симфонию прикручу к скрипту консольному, а получается нужно наоборот делать, симфония будет запускать, все инициировать

С фреймворками всегда так. Не ты управяешь потоком, а они. Енжой. Это как анал, во временем перестаешь плакать и даже начинает нравиться.

anonymous
()
Ответ на: комментарий от no-such-file

Интересно, а откуда в entity взялся find?

Я же говорю — инъекция :) У каждой модели указывается класс её бэкенда. То есть каждая модель — законченная сущность и система знает, что с ней делать без прямого привлечения контроллера.

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

Обычно модели выглядят примерно так:

<?php

class Product extends Model
{
    function table_fields()
    {
        return [
            'id',
            'artucul' => ['title' = 'Артикул'],
            'description' => ['title' = 'Описание'],
            'category_id' => ['title' => 'Группа товаров', 'class' => Category::class],
            // ...
        ];
    }
}


А вот уже в классе Model указывается и бэкенд, типа
<?php

class Model extends \B2\Obj
{
    function storage_engine() { return \B2\Storage\Mysql::class; }
    function db_name() { return \B2\Cfg::get("MY_DB"); }
}


Бэкенд же уже сам читает конфигурации, обращается к БД или иному источнику данных и инициирует ими объект или объекты.

KRoN73 ★★★★★
()
Ответ на: комментарий от gobot

Скажи как тебе удалось сделать автозагрузку, через injectObjectManager?

У меня не Симфония, у меня свой фреймворк :)

Просто метод ->load($id) каждого объекта (в общем, независимо от того, является он моделью или нет) создаёт экземпляр бэкенда и вызывает у него уже метод ->load_object($object) и этот метод инициирует объект модели нужными данными.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Как я сказал выше, это не чисто академический MVC получается

А в академическом MVC модельки и не завязаны на контекст, который есть в контроллерах. Это отдельный слой. И его можно дергать откуда угодно. Да и про clean architecture php-шные фреймворки вообще не слышали, родовое проклятье-с.

anonymous
()
Ответ на: комментарий от KRoN73

Ну вот я тоже самое хочу в симфонии, создал экземпляр и он загрузился

gobot ★★★★
() автор топика
Ответ на: комментарий от KRoN73

У каждой модели указывается класс её бэкенда. То есть каждая модель — законченная сущность и система знает, что с ней делать без прямого привлечения контроллера.

Это получился ActiveRecord. Самый главный минус с которым я не раз сталкивался - нет возможности сделать массовый insert нескольких моделей.

В EntityManager всё гораздо проще, т.к он выступает контейнером для entity и при flush может оптимизировать запрос.

no-such-file ★★★★★
()
Ответ на: комментарий от gobot

про EntityManager и прочие специфичные вещи фреймворка я не хочу знать

EntityManager это часть doctrine, он так устроен. Наподобие JPA в жабке.

Т.е. если тебе нужно только orm то достаточно одной доктрины, симфони не нужен.

no-such-file ★★★★★
()
Ответ на: комментарий от gobot

сначала какой то EntityManager взять, потом репозитарий, оттуда сделать выборку. Причем $em ещё так неявно получить можно

Ещё раз, EntityManager это контейнер для entity, который позволяет получать объекты класса, на который отображаются данные из БД и наоборот, сохранять такие объекты. Репозиторий это просто класс который содержит варианты запросов по которым нужные entity извлекаются из БД, он генерируется автоматически, но можно туда добавить свои сложные запросы если нужно.

Что касается $em, то в симфони EntityManager инстанциируется через DI-контейнер, т.е. фреймворк его инжектит в соответствующие классы (например контоллеры), но можно получить обратившись к ServiceManager напрямую.

Без использования симфони, в голой доктрине, EntityManager просто создаётся руками через фабрику. В доках доктрины всё подробно расписано, есть соответствующий пример http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/ge...

Вообще чтобы понимать как это всё работает нужно ознакомиться с паттерном Data Mapper

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Это получился ActiveRecord

Ну, в общем да. Не считая того, что AR — это контекст БД, а у меня источники данных могут быть любыми :)

нет возможности сделать массовый insert нескольких моделей

Сейчас у меня не практикуется, просто нет надобности в массовых вставках, но когда-то, в древних версиях было. Ничто не мешает не делать сохранение базы в момент создания объекта, а сохранять потом разом группу объектов, атомарно, одним запросом.

и при flush может оптимизировать запрос

Обычно у меня изменённые объекты итак сохраняются по завершению работы скрипта, а не в момент изменения. Или по специальному запросу, аналог flush. И при этом, безусловно, можно проводить оптимизацию. От позднего сохранения новых объектов я отказался как из соображения надёжности, так и для упрощения проблемы автоинкрементных идентификаторов. Удобно иметь ID объекта прямо в момент его создания, чтобы использовать тут же для связки с ним иных объектов, а не лепить сложную отложенную логику или пользоваться UUID.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Не считая того, что AR — это контекст БД

Это заблуждение. Источник данных для AR точно также может быть любым.

а сохранять потом разом группу объектов, атомарно, одним запросом.

Для этого нужен контейнер объектов - тот же EntityManager, вид сбоку.

Удобно иметь ID объекта прямо в момент его создания ... или пользоваться UUID

UUID для этого гораздо лучше, т.к. не требует обращения к БД.

no-such-file ★★★★★
()
Ответ на: комментарий от Deathstalker

А можно вас потискать?

Там есть одна родовая, так сказать, проблема — отсутствие документаци :D При чём движку непосредственно лет 15, а его корни уходят вообще где-то в 1998-й в генератор статики на QBasic :)

Так-то пакеты все открыты и все доступны:

https://packagist.org/packages/balancer/

Основная часть — https://packagist.org/packages/balancer/bors-core

Лет 7 назад я делал попытку начать писать документацию, но, поскольку движок в одиночку использую, написание документации так и обломалось на самом старте :) А сейчас то, что начал тогда делать, уже и не актуально. И собственная автозагрузка классов на Composer был заменена, и собственное именование классов, счастливо точно совпавшее с более поздним psr-0, сейчас у меня уже устаревшее в пользу psr-4...

Я начал недавно собирать эдакий мета-пакет для прототипирования и тестирования, который может быть демонстрацией движка и работы его компонентов, но это очень ранняя стадия:

https://packagist.org/packages/balancer/bors-dev

Но я не слепил пока скелетон для его развёртывания. Сейчас пока вообще в отъезде, вернусь домой, может, и сделаю :)

Вот, пример более-менее свежего сайта с открытыми исходниками:

- http://www.bionco.ru
- https://github.com/Balancer/bionco-static

Запускается оно любым index.php (одна точка входа) с содержимым

<?php

require '../composer/vendor/autoload.php';

Bionco\App::factory()
    ->run();

KRoN73 ★★★★★
()
14 октября 2017 г.
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.