Connection Refuse exception occur in drive: SQLSTATE[HY000}[2002] - php

So I am starting a docker symfony 4 project and i am trying to use a controller. I already created the database that i need by running
doctrine:database:create
and it work and created my database so the connection is good. however, when i run this code below. I get that error. I a little confuse on why mysql doesnt connect. anyone know?
Ive tried change mysql versions, composing it down and updating different mysql root and password and is not connecting.
class HospitalAdminController extends AbstractController
{
/**
* #Route("/admin/hospital/new")
*/
public function new(EntityManagerInterface $em)
{
$hospital = new Hospital();
$hospital->setName('Example Hospital')
->setPhone(8175831483)
->setAddress('123 Avenue');
$em->persist($hospital);
$em->flush();
return new Response(sprintf(
'Hiya! New Hospital id: #%d phone:%s address%s',
$hospital->getId(),
$hospital->getPhone(),
$hospital->getAddress()
));
}
}
just trying to run my controller and do a proof of concept.

Related

How do you make symfony make:crud available for API's?

In symfony you can use the command make:crud. That works excellent with forms and twig in symfony. But is there also a way to do it with api's? That I will send an POST to the route of the annotation.
Like in python;
url = 'https://127.0.0.1:8000/players/new'
myobj = {
'postName': 'postData',
}
This python code is used when i want to test a POST.
This is a piece of a make:crud what i used, only showing the New function of the CRUD. This only works with forms. I cant send directly a POST(ex, python) to it.
/**
* #Route("/players/new", name="players_new", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$player = new Players();
$form = $this->createForm(PlayersType::class, $player);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($player);
$entityManager->flush();
return $this->redirectToRoute('players_index');
}
return $this->render('players/new.html.twig', [
'player' => $player,
'form' => $form->createView(),
]);
}
I changed your endpoint slightly to make it more API friendly. In all the public facing APIs that I've built they all return JSON. That just eases the burdens for implementation. I always use a status 201 for creation, and 400 for bad requests. This serves a traditional role for RESTful API paradigms and implementations.
/**
* #Route("/players/{player}", name="get_player", methods={"GET"})
*/
public function getPlayer(Player $player): Response {
// You might need to tweak based on your Entity name
return new JsonResponse($player);
}
/**
* #Route("/players/new", name="players_new", methods={"POST"})
*/
public function newPlayer(Request $request): Response
{
$player = new Players();
$form = $this->createForm(PlayersType::class, $player);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($player);
$entityManager->flush();
} catch (\Exception $e) {
// Probably a better exception to catch here, log it somewhere
throw $e;
}
return new JsonResponse('', Response::HTTP_CREATED);
}
return new JsonResponse(
'Invalid data provided to API, please refer to documentation',
Response::HTTP_BAD_REQUEST
);
}
Changing the method from new to newPlayer was done because a method named new is confusing down the road. One thing I would also like to point out is that with Doctrine it's best to have your entities singular. Example: Player instead of Players. You can have the relationship be players within the Entity.
The Entity Game could have $players which is a relationship to OneToMany Player Entities.
Catching the exception on flush is good standard practice there. You should return a meaningful JsonResponse as well after you've logged it.
As per the official documentation, API platform is a “powerful but easy to use full-stack framework dedicated to API driven projects”. API platform helps developers significantly speed up their development process, building complex and high performance, hypermedia-driven APIs.
It ships with Symfony 4, the Doctrine ORM, a dynamic Javascript admin created with React, and React Admin, Varnish Cache server, Helm Chart to help deploy the API in a Kubernetes cluster and a Progressive Web Application skeleton. It also includes a Docker setup for providing Nginx servers to run the API and JavaScript apps. Most inspiring is the ability of API platform to natively generate project documentation with support of OpenAPI!
In this tutorial, I will take you through how to create a simple bucket list API with CRUD operations.
Prerequisites
PHP - Version 7.0 or higher.
Docker
Postgres
Getting Started
Follow the instructions below to setup your development environment:
$ mkdir demo-app
$ cd demo-app
Download the latest compressed .tar.gz distribution. Then extract it inside of our working directory and run the commands below:
$ cd api-platform-2.4.5
$ docker-compose pull
$ docker-compose up -d
The docker-compose pull command downloads all images specified in the docker-compose.yml file. In order to start the containers, run docker-compose up -d. The -d flag runs the containers in detached mode, meaning they run in the background. In order to view the container logs, you can run this command docker-compose logs -f in a separate terminal.

Laravel 5.4 MultiSite with Queues per site

My Laravel is setup with a MultiSite Middleware Provider that checks the subdomain of the address and based on this subdomain changes the connection on-the-fly to another database.
e.g.
Config::set('database.connections.mysql.host', $config['host'] );
Config::set('database.connections.mysql.database', $config['db_name'] );
Config::set('database.connections.mysql.username', $config['user']);
Config::set('database.connections.mysql.password', $config['password']);
Config::set('database.connections.mysql.prefix', $config['prefix']);
Config::set('database.connections.mysql.theme', $config['theme']);
// purge main to prevent issues (and potentially speed up connections??)
DB::disconnect('main');
DB::purge();
DB::reconnect();
return $next($request);
This all works fantastic, except that I now want to use Laravel Queues with the built-in Database driver (sync actually works fine but blocks the user experience for long report generations).
Except Artisan isn't sure which database to connect to so I'm guessing it connects to the default, which is a kind of supervisor database that stores all the subdomains and corresponding db names etc.
Note none of these databases are setup in my database conf as connections, they're stored in a singular management database as there's quite a lot of them.
I've tried cloning the built-in Queue listener and modifying it to swap to the different site connection as so:
/**
* Create a new queue listen command.
*
* #param \Illuminate\Queue\Listener $listener
* #return void
*/
public function __construct(Listener $listener)
{
// multisite swap
$site = MultiSites::where('machine_name', $this->argument('site'));
MultiSites::changeSite($site->id);
parent::__construct();
$this->setOutputHandler($this->listener = $listener);
}
But this fails with
$commandPath argument missing for the Listener class.
Trying a similar database/site swap in the fire() or handle() methods stops the $commandPath error however it simply does nothing, no feedback and doesn't begin to process any jobs from the database.
I'm at a loss how to get this working with a multisite environment, does anyone have any ideas or am I going the wrong way about this?
My ideal scenario would be being able to run a singular Queue command, have supervisor monitor that and it to skip through each database checking. But I am also willing to spawn a queue command per database/site if necessary.

Laravel 5.4 Multi-Tenant migrations, switching connections for migrations

I have a multi-tenant app that has a master database with client info, this has settings for different databases. By reading the URL on startup I can figure out the tenant they are accessing, then switch the connection and cache the settings so that it is using the correct tenants database. This part works but the problem comes up with migrations.
The regular Laravel migrations only handle the master table, so I added a migration folder for "tenants" this needs to run on all tenants for each update. To do this I use the following class
<?php
namespace App\Console\Commands\Tenants;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class UpdateTenant extends Command
{
protected $signature = 'tenant:update {slug}';
protected $description = 'Update a tenants database';
protected $migrator;
public function __construct()
{
parent::__construct();
$this->migrator = app()->make('migrator');
}
public function fire()
{
$arguments = $this->arguments();
if ($account = DB::connection('root')->table('accounts')->where('slug', '=', $arguments['slug'])->first()) {
config()->set('database.connections.tenant.database', $arguments['slug']);
$this->migrator->setConnection('tenant');
if (! $this->migrator->repositoryExists()) {
$this->call('migrate:install', ['--database' => 'tenant']);
}
$this->migrator->run([$this->laravel->basePath() . '/' . 'database/tenants']);
foreach ($this->migrator->getNotes() as $note) {
$this->output->writeln($note);
}
}
}
}
As you can see this is just for one tenant defined by the slug, I have another command to loop and call the artisan command on all tenants.
foreach ($accounts as $account) {
$this->call('tenant:update', ['slug' => $account->slug]);
}
The issue here is that although checking the value of the slug it is correctly finding the correct tenant info, the connection gets stuck on the first tenant despite switching the connection. Even if I try to switch it to the root and back it just ignores the change to the config. Is there anyway to tell laravel to reset the connection so that it will use the updated values in the config to reconnect?
Disconnect from the current connection in between tenants with:
config()->set('database.connections.tenant.database', $arguments['slug']);
DB::disconnect('tenant');<----- add this
$this->migrator->setConnection('tenant');
This will clean up the resource connection and force the app to re-establish itself with the correct configuration settings.

Modding Laravel 5.1 Custom Packge Classes to Enable Auto Completion and Hints

I wrote a basic package for augmenting ldap into laravel
it can now parse subschema do searchs and generate ldif entries,my problem is
this package is driver based as in
when you create you first instance from the manager the front class
i do like this
$driver=new ldapman('openldap')->getDriverInstance();
or in Larvel 5.1
$man=app('Ldapman',['drivername'=>'openldap']);
$driver=$man->getDriverInstance();
and that's lead to constructer like this,
public function __construct( $driver,$type='driver')
{
$drivername=ucfirst($this->drivername);
$drivername.=$type;
$this->driverArray[$type]=null;
if(file_exists(__DIR__."/driver/$drivername.php"))
{
include_once(__DIR__."/driver/$drivername.php");
$drivername="\\Chromax\\Ldapman\\driver\\".$drivername;
if(isset($config)&&!is_null($config))
{
$this->driverArray[$type]=new $drivername($this->config);
}else{
$this->driverArray[$type]=new $drivername();
}
if($this->driverArray[$type] instanceof $drivername)
{
}else{
throw new \Exception("201 Class Not Found");
}
}
else
{
throw new \Exception("200 Driver Not Found");
}
}
this approach is fine and it helps me well but when i sent this package to a friend who was costumed to auto completion he had a hard time working with it
so i want to mod it to support completion
notice : my IDE is PHPSTROM

Using MongoDb in the PHP Phalcon framework

I am currently experimenting with the Phalcon Framework, and running into some complications when I attempt to save content into the Mongo Database. I can correctly setup the MySQL database without issues. Whenever I send the simple request through I get a 500 Internal server error (checking devTools). I have setup everything accordingly as the documentation specifies.
This is my simple index.php bootstrap Mongo initialisation along with the collection manager:
// Setting Mongo Connection
$di->set('mongo', function() {
$mongo = new Mongo();
return $mongo->selectDb("phalcon");
}, true);
// Setting up the collection Manager
$di->set('collectionManager', function(){
return new Phalcon\Mvc\Collection\Manager();
}, true);
This is my controller handling the request:
public function createAction() {
$user = new User();
$user->firstname = "Test ACC";
$user->lastname = "tester";
$user->password = "password";
$user->email = "testing#example.com";
if($user->create() == false) {
echo 'Failed to insert into the database' . "\n";
foreach($user->getMessages as $message) {
echo $message . "\n";
}
} else {
echo 'Happy Days, it worked';
}
}
And finally my simple User class:
class User extends \Phalcon\Mvc\Collection {
public $firstname;
public $lastname;
public $email;
public $password;
public $created_at = date('Y-m-d H:i:s');
}
Much appreciated for everyones input/suggestions.
i think it's because your installation of Mongo is not valid.
try printing phpinfo() and check if mongo is loaded at all, if not - install it, add to ini files (if you use cli, don't forget to add to cli ini too) and reach the moment, when mongo is fully loaded.
try mongo w/o phalcon. any simple connection/insertation. you can see here: Fatal Error - 'Mongo' class not found that there are problems with apache module version for some people. Try reinstalling different mongo version.
if you can print this out:
echo Phalcon\Version::get();
there should be no problems with phalcon instalation
to validate mongo installation, try any of examples from php.net:
http://www.php.net/manual/en/mongo.tutorial.php
A little bit late, but for anyone else facing this issue, it would be a good idea to try and connect to mongo (run "mongo" in your terminal) to ensure that mongo is setup correctly in your dev environment.
Also, I usually find in this sort of situation, that adding a collection to a database in mongo and then testing the CRUD process with a simple read helps move things along. If all is well at this stage, then you know your app is able to connect and you can proceed to writes, and so on.
This looks useful.

Categories