I'm trying to make my symfony 3.0 app capable to work with multiple kernel.
real aim : Multiple applications in one project
Generally everything is OK. I edited bin/console it's content exactly as the following. It works exactly and results what I need via php bin/console --app=api
But when I execute composer install bin/console throws the Exception naturally it doesn't knows about --app parameter. I want to make something like composer install --app=api and desired behaviour it would pass the parameter to bin/console I checked documentation and almost every pixel of the internet couldn't find a solution.
#!/usr/bin/env php
<?php
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Debug\Debug;
// if you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
//umask(0000);
set_time_limit(0);
/**
* #var Composer\Autoload\ClassLoader $loader
*/
$loader = require __DIR__.'/../apps/autoload.php';
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$app = $input->getParameterOption(array('--app', '-a'));
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
if ($debug) {
Debug::enable();
}
switch ($app) {
case 'api':
$kernel = new ApiKernel($env, $debug);
break;
case 'frontend':
$kernel = new FrontendKernel($env, $debug);
break;
default:
throw new \InvalidArgumentException("[--app|-a=<app>] app: api|frontend");
break;
}
$application = new Application($kernel);
$application->getDefinition()->addOptions([
new InputOption('--app', '-a', InputOption::VALUE_REQUIRED, 'The application to operate in.'),
]);
$application->run($input);
You can use composer install --no-scripts to prevent automatically running app/console after installation.
Or you can remove the the bin/console commands from the scripts section in your composer.json altogether, which probably makes more sense. See https://github.com/symfony/symfony-standard/blob/master/composer.json#L33-L34
Or you can use environment variables instead of arguments.
Related
How could Laravel Artisan commands be executed on the server by sending the command as a query parameter in an URL?
Without commencing new dockerfile you cant run laravel artisan commands if those need mysql connection command line. If you are searching for quick and dirty hack here it is:
In order to work on existing php-fpm-alpine, use artisan commands from the web interface those code can be added to index.php (generally located in /public directory)
if($debugmode)
if(#$_REQUEST['artisan']){
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$vars = explode(' ', $_REQUEST['artisan']);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArrayInput($vars),
new Symfony\Component\Console\Output\ConsoleOutput
);
return '';
}
those shoud come between
$app = require_once __DIR__.'/bootstrap/app.php';
and
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
usage http://localhost/?artisan=vendor:publish
I've written a custom Artisan command (let's call it MyDusk.php) that expands/abstracts some of the functionality of the core Dusk command.
This custom command extends Laravel\Dusk\Console\DuskCommand from within the Dusk package.
The problem is, on production the Dusk package is not installed (it's under require-dev in composer.json)
So when composer is generating its autoload files on production, it errors out when it gets to MyDusk.php because it can't find Laravel\Dusk\Console\DuskCommand.
PHP Fatal error: Class 'Laravel\Dusk\Console\DuskCommand' not found in app/Console/Commands/Dusk.php on line 10
In Dusk.php line 10:
Class 'Laravel\Dusk\Console\DuskCommand' not found
I tried moving the Dusk package to require so it would be available on production (not ideal, I know), but there's a line in the core Dusk service provider that throws an exception when it's run on production preventing this:
# From: vendor/laravel/dusk/src/DuskServiceProvider.php
if ($this->app->environment('production')) {
throw new Exception('It is unsafe to run Dusk in production.');
}
I'm trying to think of the most elegant solution to allow for my custom Dusk command to be part of the application and accessible locally, without throwing errors on production.
One idea: Write my Dusk command as its own package, that's also only in require-dev.
Any other ideas?
I just took a look at the API, you could do this:
You could move your command to App\Console\Commmands\Local\DuskCommand.php.
By default, if you check the commands() method in the Kernel, it's only going to load commands found in App\Console\Commands. This will not include the sub-directories.
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
This is the default commands() method. You could switch this implementation to the one below:
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$paths = [
__DIR__ . '/Commands'
];
if(app()->environment('local')) {
$paths[] = __DIR__ . '/Commands/Local';
}
$this->load($paths);
require base_path('routes/console.php');
}
So, in local, we are also going to load commands based in App\Console\Commands\Local.
Admittedly, I didn't give this a try myself, but I am assuming that it should work.
Edit: I gave it a try and it seems to be working just fine. I thought, I'd try to explain it a bit more. Basically, after doing a composer dump-autoload, Laravel is listening to this event and doing two things:
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover --ansi"
]
The second one is trying to run the Auto-Package Discovery command and this is where it will fail. The Artisan executable actually boots the application with the Console Kernel.
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
While resolving the Kernel, it will also try to boot up the Commands that it needs so that they are available to Artisan, and this is where it fails.
However, like I mentioned above, if you only boot the Commands you need in production, this issue won't happen.
Accepted answer seems not to work in Laravel 6. This worked for me:
Create your command with php artisan make:command YourCommand and move it to app/Console/Local.
Change its namespace to App\Console\Local.
Then, in app/Console/Kernel.php:
protected function commands()
{
$paths = [
__DIR__ . '/Commands'
];
if(app()->environment('local')) {
$paths[] = __DIR__ . '/Local';
}
$this->load($paths);
require base_path('routes/console.php');
}
Enjoy ;)
How can I get a service from the command class? I have been trying to use ContainerAwareCommand as the parent of my command class, and then just using $this->getContainer()->get('my_service'), but when I run the command in cli, I get the following error:
Call to undefined method Symfony\Component\Console\Application::getKernel()
inside the getContainer() method of the ContainerAwareCommand class.
The file through which I run the command is:
<?php
require_once __DIR__.'/../vendor/autoload.php';
require_once __DIR__.'/AppKernel.php';
use AppBundle\Console\Command\ChangeEmailCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
if ($debug) {
Debug::enable();
}
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->add(new ChangeEmailCommand());
$application->run();
You have to use the Application of the FrameworkBundle instead of the Console component. This class extends the one in the Console component, but adds awareness of the Kernel and the Container. Your Application version doesn't have this awareness (as it's designed for standalone use, outside of the Symfony context), resulting in a "method getKernel() does not exists".
So change this:
use Symfony\Component\Console\Application;
To:
use Symfony\Bundle\FrameworkBundle\Console\Application;
Btw, normally you won't need to create this file yourself. You can just use app/console in the Standard Edition: https://github.com/symfony/symfony-standard/blob/2.7/app/console when you installed Symfony using the installer/composer create-project.
I have the following new environment:
<?php
use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
// Use APC for autoloading to improve performance
// Change 'sf2' by the prefix you want in order to prevent key conflict with another application
/*
$loader = new ApcClassLoader('sf2', $loader);
$loader->register(true);
*/
require_once __DIR__.'/../app/AppKernel.php';
//require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppKernel('mobile', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
however when I do the following:
sudo php app/console assetic:dump --env=mobile
it gives me:
Clearing the cache for the mobile environment with debug true
How is it possible that debug is set to true while I have specifically in the new AppKernel('mobile' false);
I have cleared the cache and everything but it is still the same
When I do the following:
$kernel = $this->get('kernel');
ladybug_dump($kernel->isDebug());
this returns false, however it's just the console command that is not getting it right
sudo php app/console assetic:dump --env=dev --no-debug
after working with my project on dev mod, i found some problems with prod on OVH.
it shows me a blank page ! i try to follow the issue on app.php and i found that the problem persist with the execution of $response = $kernel->handle($request); and it don't logging on prod.
so when i change the row on app.php : $kernel = new AppKernel('prod', false); with $kernel = new AppKernel('dev', false); it works well !!!
here's my app.php
<?php
/*
* This file is part of the Sonata package.
*
* (c) Thomas Rabaix <thomas.rabaix#sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
umask(0000);
require_once __DIR__ . '/../app/bootstrap.php.cache';
require_once __DIR__ . '/../app/AppKernel.php';
//use Symfony\Component\HttpFoundation\Request;
// if you want to use the SonataPageBundle with multisite
// using different relative paths, you must change the request
// object to use the SiteRequest
use Sonata\PageBundle\Request\SiteRequest as Request;
$request = Request::createFromGlobals();
$kernel = new AppKernel('prod', false);
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
EDIT :
in dev and prod local mode test it works well with
php app/console cache:clear --env=prod --no-debug
php app/console assets:install web_directory
php app/console assetic:dump web_directory
should i add or install php5 on my project ?
EDIT :
my project contains : sonata-project, fosUserBundle,etc...
EDIT
the problem was on config_prod.xml
doctrine:
orm:
entity_managers:
default:
metadata_cache_driver: apc
query_cache_driver: apc
result_cache_driver: apc
intil now after it return an error 500 ! why ? because of apc was not enabled !
so my question how to enable apc on OVH pro !
Go to web/config.php and comment ot the following lines:
if (!in_array(#$_SERVER['REMOTE_ADDR'], array(
'127.0.0.1',
'::1',
))) {
header('HTTP/1.0 403 Forbidden');
exit('This script is only accessible from localhost.');
}
That will enable the config.php to be called from "extern". Don't forget to remove the comments after you've checked everything.
If you have console access on the production server, enter the root directory of your project and call php app/check.php to run the checks on the console.