Monolog in Silex application - php

I try to use Monolog in my Silex application, according to the doc
http://silex.sensiolabs.org/doc/master/providers/monolog.html
I declare MonologServiceProvider in the app.php file as follow:
use Silex\Provider\MonologServiceProvider;
$app->register(new MonologServiceProvider(), array(
'monolog.logfile' => __DIR__ . '/../files/logs/log.log',
));
And I try to write in my log.log file on the controler:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// In a controler
$app['monolog']->info("test");
$app['monolog']->debug("test");
$app['monolog']->warning("test");
$app['monolog']->error("test");
I don't have any error, but it is not working at all.
I just wan't to put my "test" message in my log.log file, how can I do that ?
Thanks for help

I can't really answer your question based on the info you've given, but it's a slow-news day here, so strummed-up a working Silex site with working logging. All the files are on Github, but I'll repeat them here for ease of reading.
composer.json
{
"require" : {
"silex/silex" : "^2.0",
"monolog/monolog" : "^1.0"
},
"autoload" : {
"psr-4" : {
"community\\" : "src/"
}
}
}
public/index.php
<?php
use \community\app\Application;
require_once realpath(__DIR__ . '/../vendor/autoload.php');
$app = new Application();
$app["debug"] = true;
$app->run();
src/app/Application.php
<?php
namespace community\app;
use \Silex\Application as SilexApplication;
use Silex\Provider\MonologServiceProvider;
class Application extends SilexApplication {
function __construct() {
parent::__construct();
$this->registerServices();
$this->mountControllers();
}
function registerServices(){
$this->register(new MonologServiceProvider(), [
"monolog.logfile" => realpath(__DIR__ . "/../../log") . "/general.log"
]);
}
function mountControllers() {
$this->get('/testLog', 'community\controller\TestLogController::doGet');
}
}
src/controller/TestLogController.php
<?php
namespace community\controller;
use community\app\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class TestLogController {
public function doGet(Request $request, Application $app) {
$app["monolog"]->info("hi!");
return new Response("All good", Response::HTTP_OK);
}
}
That writes to log/general.log as follows:
[2016-12-28 13:58:05] app.INFO: hi! [] []
One thing I noticed is that if the path to the log file is bung, then Monolog just seems to swallow it (which is not exactly ideal). This could well be your issue.
Anyway, grab the code above and mess around with it. Hopefully you'll be able to work out the differences between yours and mine, and get yours working.

Related

Symfony Routing Component not routing url

I have mvc php cms like this folder structure:
application
---admin
--------controller
--------model
--------view
--------language
---catalog
--------controller
------------------IndexController.php
--------model
--------view
--------language
core
--------controller.php
//...more
public
--------index.php
vendor
I install symfony/router component for help my route url using composer json:
{
"autoload": {
"psr-4": {"App\\": "application/"}
},
"require-dev":{
"symfony/routing" : "*"
}
}
Now with route documents I add this code for routing in index.php:
require '../vendor/autoload.php';
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$route = new Route('/index', array('_controller' => 'App\Catalog\Controller\IndexController\index'));
$routes = new RouteCollection();
$routes->add('route_name', $route);
$context = new RequestContext('/');
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match('/index');
In My IndexController I have :
namespace App\Catalog\Controller;
class IndexController {
public function __construct()
{
echo 'Construct';
}
public function index(){
echo'Im here';
}
}
Now in Action I work in this url: localhost:8888/mvc/index and can't see result : Im here IndexController.
How do symfony routing url work and find controller in my mvc structure? thank for any practice And Help.
The request context should be populated with the actual URI that's hitting the application. Instead of trying to do this yourself you can use the HTTP Foundation package from symfony to populate this:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RequestContext;
$context = new RequestContext();
$context->fromRequest(Request::createFromGlobals());
It's also documented here: https://symfony.com/doc/current/components/routing.html#components-routing-http-foundation
After the matching ($parameters = $matcher->match('/index');) you can use the _controller key of the parameters to instantiate the controller and dispatch the action. My suggestion would be to replace the last \ with a different symbol for easy splitting, like App\Controller\Something::index.
You can then do the following:
list($controllerClassName, $action) = explode($parameters['_controller']);
$controller = new $controllerClassName();
$controller->{$action}();
Which should echo the response you have in your controller class.

Can't load class on Slim 3

I'm trying to load my custom classes for the model on Slim 3 (using the skeleton) so I made this:
In app/composer.json:
"autoload": {
"psr-4": {
"App\\Classes\\": "/src/classes"
}
},
In routes.php I have this setting:
<?php
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Container;
// Routes
$app->get('/sugiere', function (Request $request, Response $response, array $args) {
// Sample log message
$this->logger->info("Slim-Skeleton '/' route");
$cat_mapper = new \App\Classes\CategoryMapper($this->db);
$comuna_mapper = new \App\Classes\ComunaMapper($this->db);
$lang_mapper = new \App\Classes\LanguageMapper($this->db);
$netw_mapper = new \App\Classes\NetworkMapper($this->db);
$com_list = $com_mapper->getComunaList();
$cat_list = $cat_mapper->getCategoryList();
$lang_list = $lang_mapper->getLangList();
$netw_list = $netw_mapper->getNetworkList();
By the way I added to all classes a namespace App\Classes on top.
Your path /src/classes looks incorrect. It's unlikely your src directory is in the filesystem root.
Change your composer.json file to
"autoload": {
"psr-4": {
"App\\Classes\\": "src/classes/"
}
}
and run
composer dump-autoload
to re-generate the autoload.php file.
See https://getcomposer.org/doc/01-basic-usage.md#autoloading

Slim Framework - Class 'Slim\\Middleware' not found

I'm trying to create a custom middleware class and can't seem to call extend \Slim\Middleware because it's not found.
This is my index.php
<?php
require __DIR__ . '/../vendor/autoload.php';
session_start();
// Instantiate the app
$settings = require __DIR__ . '/../src/settings.php';
$app = new \Slim\App($settings);
// Register middleware
require __DIR__ . '/../src/middleware.php';
// Run app
$app->run();
This is my middleware.php
<?php
require_once("tester_auth.php");
$app->add(new TestAuth());
This is my tester_auth.php which is the custom middleware file
<?php
use Slim\Middleware;
class TestAuth extends \Slim\Middleware {
public function __construct() {
//Define the urls that you want to exclude from Authentication, aka public urls
$this->whiteList = array('\/login');
}
public function deny_access() {
$res = $this->app->response();
$res->status(401);
}
public function isPublicUrl($url) {
$patterns_flattened = implode('|', $this->whiteList);
$matches = null;
preg_match('/' . $patterns_flattened . '/', $url, $matches);
return (count($matches) > 0);
}
public function call() {
//Get the token sent from jquery
$tokenAuth = $this->app->request->headers->get('Authorization');
//We can check if the url requested is public or protected
if ($this->isPublicUrl($this->app->request->getPathInfo())) {
//if public, then we just call the next middleware and continue execution normally
$this->next->call();
} else {
$this->deny_access();
}
}
}
It successfully gets to my TestAuth but gives me the error Class 'Slim\\Middleware' not found in /var/www/html/src/tester_auth.php on line 6 ...
Edit:
At first, I was having this issue because my composer.json didn't have middleware installed but I have since updated it and it's there now but still having the same issue..
"require": {
"php": ">=5.5.0",
"slim/slim": "^3.8",
"slim/php-view": "^2.0",
"slim/middleware": "*",
"monolog/monolog": "^1.17"
}
Try to restart your HTTP server (ngixn, PHP web server,..) in case it caches some PHP.
BTW, slim/middleware is for Slim 2., but you are using 3..

Instantiating twig in a namespaced class

I'm running into some issues trying to figure out how to use Twig in a specific way. I'm trying to write a view class that I can use in my application regardless of what template system is installed, that way the only things I would have to change would be the templates themselves and the view class.
However, when I try and create the twig objects in the class, I get Fatal error: Class 'Template\Twig_Loader_Filesystem' not found errors, and I'm not really sure what I'm missing.
Can someone point me in the right direction?
Here's what I've got so far...
composer.json
{
"name": "Movies",
"description": "Find movies",
"require": {
"ext-curl": "*",
"twig/twig": "~1.0"
},
"autoload": {
"classmap": [
"app/classes"
]
}
}
index.php
require_once 'app/app.php';
use Template\Template;
echo Template::render('hello.html', array('name' => 'bob', 'age' => '33'));
app/app.php
define('APP_DIRECTORY', __DIR__ . '/..');
require_once APP_DIRECTORY . '/vendor/autoload.php';
app/classes/Template.class.php
namespace Template;
class Template {
static function render($template_name, $template_data = array()) {
$loader = new Twig_Loader_Filesystem(APP_DIRECTORY . '/app/templates');
$twig = new Twig_Environment($loader);
return $twig->render('hello.html', array('name' => 'lisa', 'age' => '33'));
}
}
Ok, it turned out whenever I would try and include the twig namespaces on my Template class, I was doing it wrong. Looking at other projects my organization has put together, it turns out just adding
use Twig_Environment;
use Twig_Loader_Filesystem;
to the class is enough. I wasn't sure if I actually had to add anything, since the Autoloader was included, or if I had to include part of the path, like Twig_Twig/Loader/Filesystem or something like that. Obviously neither of those was working.

Unable to find controller in Silex Application

Good morning,
I have been developing an application using Silex for the past couple of weeks and last night I either made a change to my code or something was updated as part of updating composer but it will not work.
I am using the 'Igorw\ConfigServiceProvider' to load up my routes which link to my configured controllers. But when I access the webpage I get the error message:
InvalidArgumentException: Unable to find controller "controllers.admin:index".
My files are as follows
composer.json
{
"require": {
"silex/silex": "1.2.*#dev",
"igorw/config-service-provider": "1.2.*#dev",
"symfony/yaml": "2.5.*#dev"
},
"autoload": {
"psr-4": {
"Turtle\\Controllers\\": "src/turtle/controllers"
}
}
}
config/routes.yml
config.routes:
admin:
pattern: /admin
defaults: { _controller: 'controllers.admin:index' }
method: GET
web/index.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use \Igorw\Silex\ConfigServiceProvider;
use \Turtle\Controllers\AdminController;
$app = new Silex\Application;
$app["debug"] = true;
// load the routes
$app -> register (new ConfigServiceProvider(__DIR__ . "/../config/routes.yml"));
foreach ($app["config.routes"] as $name => $route) {
$app -> match($route["pattern"], $route["defaults"]["_controller"]) -> bind($name) -> method(isset($route["method"]) ? $route["method"] : "GET");
}
// register the classes
$app["controllers.admin"] = $app -> share(function($app) {
return new AdminController($app);
});
$app -> run();
src/turtle/controllers/AdminController.php
<?php
namespace Turtle\Controllers;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
class AdminController {
protected $app;
public function __construct(Application $app) {
$this -> app = $app;
}
public function index (Request $request) {
return "Hello World!";
}
}
I have checked the $app variable and it contains an instantiated AdminController class, but for some reason the system is picking up the controller properly. I really do not understand what has happened and can only put it down to an obscure mistake or an update.
Can anyone shed any light on this please?
Thanks, Russell
I cross posted this on the Silex GitHub issue site at https://github.com/silexphp/Silex/issues/919 and the problem has been pointed out. Kudos to Dave Marshall.
The web/index.php file is not registering the Silex ServerControllerServiceProvider. After adding this in the system now works. The updated file now looks like:
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use \Igorw\Silex\ConfigServiceProvider;
use \Turtle\Controllers\AdminController;
$app = new Silex\Application;
$app["debug"] = true;
$app->register(new Silex\Provider\ServiceControllerServiceProvider());
// load the routes
$app -> register (new ConfigServiceProvider(__DIR__ . "/../config/routes.yml"));
foreach ($app["config.routes"] as $name => $route) {
$app -> match($route["pattern"], $route["defaults"]["_controller"]) -> bind($name) -> method(isset($route["method"]) ? $route["method"] : "GET");
}
// register the classes
$app["controllers.admin"] = $app -> share(function($app) {
return new AdminController($app);
});
$app -> run();
I must have removed the line inadvertently when I was re-organising the files.

Categories