I have created a simple demo Laravel Nova Tool to fetch some remote data. I need to fetch it with PHP as it requires authorization, anyway this code inside api.php:
$client = new \GuzzleHttp\Client();
Route::get('/employees', function (Request $request) use ($client) {
$base_url = 'https://example.com';
$get_token_url = $base_url . '/auth/access_token?user_id=smthg&user_secret=smthg';
$request = $client->get($get_token_url);
$response = $request->getBody();
return $response;
});
It doesn't work as I'm getting Class 'GuzzleHttp\Client' not found. I need this dependency inside the Tool. I have installed Guzzle using composer require guzzlehttp/guzzle inside the Tool and composer.json is updated accordingly. It is a namespace issue. My question is how can I correctly namespace it?
You need to remove the slash before GuzzleHttp\Client. Also, the $request parameter gets overridden. In your routes api.php try this instead.
use Illuminate\Http\Request;
$client = new GuzzleHttp\Client();
Route::get('/employees', function (Request $request) use ($client) {
$base_url = 'https://example.com';
$get_token_url = $base_url.'/auth/access_token?user_id=smthg&user_secret=smthg';
$response = $client->get($get_token_url);
return $response->getBody();
});
Related
I am trying to learn slim framework and I am following the tutorial. What I would like is a detailed explanation of what the be low snippet of code is doing within the slim environment.
$app->get('/client/{name}'
The reason that I am asking is because in keep getting route not found. But I have yet to figure out why. The base route works. But when I added the twig and tried to route to that. It fails.
Now comes the code:
This part is in my webroot/public/index.php
<?php
use DI\Container;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Twig\Error\LoaderError;
require __DIR__ . '/../vendor/autoload.php';
$container = new Container;
$settings = require __DIR__ . '/../app/settings.php';
$settings($container);
AppFactory::setContainer($container);
$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->addErrorMiddleware(true, true, true);
// Create Twig
$twigPath = __DIR__ . "/../templates";
$twig = '';
try {
$twig = Twig::create($twigPath, ['cache' => false]);
} catch (LoaderError $e) {
echo "Error " . $e->getMessage();
}
// Add Twig-View Middleware
$app->add(TwigMiddleware::create($app, $twig));
$routes = require __DIR__ . '/../app/routes.php';
$routes($app);
$app->run();
This part is in the routes.php:
<?php
use Slim\App;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
return function (App $app) {
$app->get('/', function (Request $request, Response $response, array $args) {
$response->getBody()->write("Hello world! Really?");
return $response;
});
$app->get('/client/{name}', function (Request $request, Response $response, $args) {
$view = Twig::fromRequest($request);
return $view->render($response, 'client_profiles.html', [
'name' => $args['name']
]);
})->setName('profile');
};
The first route works fine the second does not. According to what I am reading. It should work. https://www.slimframework.com/docs/v4/features/templates.html
I feel that if I knew what get is looking to do. I may be able to fix it and build a proper route.
When I dig into the $app->get which connects with the RouterCollecorProxy.php. There is the $pattern variable and $callable. The callable is the anonymous function that comes after the common in the
$app->get('/client/{name}', function <- this is the callable, right?
I see the map class which takes me to the createRoute which returns the $methods, $pattern, callable and a few other things.
I think the pattern is where my problem is.
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.
I am completelly new to Slim. I have used php for the last 3-4 years but I have always done everything from scratch. I want to learn this frameworks for some rest services I have to do.
I have followed a tutorial on the slim webpage to get a simple rest service working but I want to add a log system to see what is happening when something goes wrong or wathever.
This is what I have right know:
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../Slim/Slim.php';
\Slim\Slim::requisterAutoloader();
$application = new \Slim\App();
$logger = $application->log;
$logger->setEnabled(true);
$logger->setLevel(\Slim\Log::DEBUG);
$application->get(
'/hello/user',
function ()
{
GLOBAL $logger;
$logger->info("starting the handling function");
echo "<data>response</data>";
$logger->info("ending handling function");
});
$application->run();
?>
I also tried with monolog but I didn't get it working.
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
require '../vendor/autoload.php';
$logger = new \Flynsarmy\SlimMonolog\Log\MonologWriter(array(
'handlers' => array(
new \Monolog\Handler\StreamHandler('./logs/'.date('Y-m-d').'.log'),
),
));
$app = new Slim\App(array(
'log.writer' => $logger,
));
$app->get('/hello/{name}', function (Request $request, Response $response){
$name = $request->getAttribute('name');
$response->getBody()->write("Hello, $name");
//$app->log->writer("hola");
$this->logger->info("Slim-Skeleton '/' route");
return $response;
});
$app->run();
What I would really want is to have a daily log with warnings, debug, info... in the same file. Changing the file every day.
The slim-skeleton application shows how to integrate monolog.
Register the logger with the DI container:
$container['logger'] = function ($c) {
$settings = $c->get('settings')['logger'];
$logger = new \Monolog\Logger('test-app');
$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stdout', \Monolog\Logger::DEBUG));
return $logger;
};
Use it in your closure:
$app->get('/hello/{name}', function (Request $request, Response $response){
$name = $request->getAttribute('name');
$response->getBody()->write("Hello, $name");
$this->get('logger')->info("Slim-Skeleton '/' route");
return $response;
});
The logs will out output to stdout, so you'll see the in your apache error log or if you're using the built-in PHP server, in the terminal.
I have been at this for hours now and can not seem to figure out why it's not working. This my first time using SLIM and my first exposure to middleware. I am trying to follow the tutorial listed on the slim website but just can't get to work.
My bootstrap code:
<?php
require '../vendor/autoload.php';
$app = new Slim\Slim();
$app->get('/test', function() {
echo 'Hello, World';
});
$mw = function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
};
$app->add($mw);
$app->run();
When I run just my slim url without the middleware it runs fine. I get Hello, World as the output when I runt http://mysite/test. But when I add the middleware code as listed on the slim site I get the following error:
Catchable fatal error: Argument 1 passed to Slim\Slim::add() must be an instance of Slim\Middleware, instance of Closure given, called in /Applications/XAMPP/xamppfiles/htdocs/project/api/public/index.php on line 22 and defined in /Applications/XAMPP/xamppfiles/htdocs/academy/api/vendor/slim/slim/Slim/Slim.php on line 1267
Am I missing something? Does the middleware require some other setup? The slim documentation is not very helpful when it comes to this. Any help appreciated.
You seem to have installed Slim 2. You are also mixing Slim 2 and Slim 3 syntax. To install Slim 3 issue the following command.
$ composer install slim/slim
Then use code like following:
<?php
require "vendor/autoload.php";
$app = new \Slim\App;
$mw = function ($request, $response, $next) {
$response->getBody()->write("BEFORE");
$response = $next($request, $response);
$response->getBody()->write("AFTER");
return $response;
};
$app->add($mw);
$app->get("/test", function ($request, $response) {
echo "Hello, World";
});
$app->run();
Having a NuSOAP web service defined in an inline route closure function works great, but having it in a route closure controller does not.
Example: working
routes.php:
Route::any('api', function() {
require_once ('nusoap.php');
$server = new \nusoap_server();
$server->configureWSDL('TestService', false, url('api'));
$server->register('test',
array('input' => 'xsd:string'),
array('output' => 'xsd:string'),
);
function test($input){
return $input;
}
$rawPostData = file_get_contents("php://input");
return \Response::make($server->service($rawPostData), 200, array('Content-Type' => 'text/xml; charset=ISO-8859-1'));
});
SOAP Test Client
require_once('nusoap.php');
$client = new \nusoap_client('http://my-laravel-installation.com/api?wsdl', true);
$result = $client->call("test", "HelloWorld");
print_r($result); exit();
response
HelloWorld
This works as expected.
Example: not working
Moving the code to a dedicated controller breaks it:
routes.php:
Route::any('api', 'SoapController#server');
SoapController.php:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SoapController extends Controller {
public function server() {
require_once ('nusoap.php');
$server = new \nusoap_server();
$server->configureWSDL('TestService', false, url('api'));
$server->register('test',
array('input' => 'xsd:string'),
array('output' => 'xsd:string'),
);
function test($input){
return $input;
}
$rawPostData = file_get_contents("php://input");
return \Response::make($server->service($rawPostData), 200, array('Content-Type' => 'text/xml; charset=ISO-8859-1'));
}
}
SOAP Test Client
require_once('nusoap.php');
$client = new \nusoap_client('http://my-laravel-installation.com/api?wsdl', true);
$result = $client->call("test", "HelloWorld");
print_r($result); exit();
response
"method 'test' ('test') not defined in service('' '')
Steps To Reproduce:
Install a fresh copy of Laravel v5.2.45
Download the last NuSOAP version (v0.9.5)
Define the route for the NuSOAP Web Service - copy and paste the code from above
Create the SoapController - copy and paste the code from above
Create a new temp route to act as the SOAP client, and copy and paste the code beneath SOAP Test Client above into this route's closure function
Load the temp route page in the browser to execute a SOAP call to the Web Service
Conclusion:
This indicates, that for some reason, the output is different when using an inline route function versus using a dedicated route controller.
How could this be?
Your insight greatly appreciated:
If you have:
any experience with this and you have a solution
or, you have an idea on why this could occur
or, you have any thoughts on why having the NuSOAP code in the controller generates a different response than having it in an inline route function
...please chime in.
Thank you for your thoughts!
I have a simple solution for this.
Just install nusoap via composer.
composer require econea/nusoap
Call nusoap as needed:
$client = new \nusoap_client('http://my-laravel-installation.com/api?wsdl', true);
I hope that helps.
CSRF validation should be passive for current laravel versions.
app\Http\Middleware\VerifyCsrfToken.php
protected $except = [
'your way'
];
Must be.