I am trying to use guzzle 6.x on a CakePHP 2.x application.
What I need to do is to initialize Guzzle Client to some of my controllers but on the controllers that it will be loaded I need it to be loaded with the same configuration.
Basically what I don't know is which is the best approach to implement it. I was thinking about the following:
Shall I create a function in AppController that will create and return a Guzzle object and then save it to a protected property inside AppController? Maybe a function like setUpGuzzle() and call this function on the Controllers I need to load Guzzle Client.
Shall I create a component and then load Guzzle Client to a public property of this component. Then I could use it like this $this->HttpClient->client->post()
Shall I create a component and write one function for each of Guzzle public function? So I will have something like this $this->HttpClient->post().
Thing is I don't like any of the above and I was hopping maybe there could be another way to do this. For example create a components which loads the Guzzle Client in a controller or loads the Guzzle Client inside the component collection.
Do you really need Guzzle? I agree that the old Cake2 HTTP socket is old fashioned but is there something it can't do that requires you to add yet another lib?
Use a trait, as long as you're not stuck to an ancient php version this is a clean solution. Here is some pseudo-code that will give you the high level idea:
trait HttpSocket {
protected $_httpSocket = null;
protected $_httpSocketConfig = [
// Default config goes here
];
public function getHttpSocket() {
if (empty($this->_httpSocket)) {
// Not sure how the constructur works, so it's just an example
$this->_httpSocket = new Guzzle($this->_httpSocketConfig);
}
return $this->_httpSocket;
}
}
If you ever need to change the config or the whole socket implement ion you just have to change it in a single place without the overhead of a component. Also this can be use in any class, not just controllers. What you're looking for is more or less a simple factory like method, no need for a whole controller.
If you can't use a trait then you'll have to use a component or just put the above code not inside a trait nor a component but directly inside your AppController, but you won't be able to use it outside the scope of the controllers that inherit that controller then.
Related
I could not find any information related two types of session access methods.
$request->session() from HTTP request instance and session() from session helper in Laravel 5.3 .
Is there any difference or which one to use when ?
How to send a get request to below controller method when using P.H.P unit
public function testMyMethod(Request $request){
$userExist = $request->session()->exists('user_id');
}
The Service Container is the core of the Laravel architecture. All services, components, and dependencies are registered there, and you can ask for any of them whenever you need it.
But Laravel provides more than one way to "ask for it". You have the global helper functions, you have facades, you have the "proper", "purer" injection of the component instance in the method signature. I think a big part of the philosophy of Laravel is a clean, easy, intuitive API. And in this case, it can be left up to your personal preference to define what "clean and easy" is, and whatever matches your style will be, by definition, intuitive to you.
I know there have been heated debates in the PHP community as to which method is "best", facades have been controversial, traditional dependency injection OOP purists say the only right way may be injecting the object with the controller method signature...
In the end, any of this various methods just grab the object from the same service container bag. It makes no difference performance-wise (I bet two function calls of indirection won't hit your performance) or otherwise. So, use whatever suits your style better. I personally do the "proper" injection anyway if I'm in a typical controller, but maybe I use the global helper if it makes for a cleaner, more readable code in its context.
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Session\Session;
use Facades\Illuminate\Contracts\Session\Session as SessionRealTimeFacade;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Request as RequestFacade;
use Illuminate\Support\Facades\Session as SessionFacade;
use PHPUnit\Framework\Assert;
class TestController extends Controller
{
public function sessionTest(Request $request, Session $session)
{
$options = [
$request->session()->get('_token'),
session()->get('_token'),
session('_token'),
$session->get('_token'),
SessionFacade::get('_token'),
SessionRealTimeFacade::get('_token'),
app('session')->get('_token'),
];
array_reduce(
$options,
function ($one, $other) {
Assert::assertEquals($one, $other);
return $other;
},
array_shift($options)
);
return 'All tests passed!';
}
}
And by the way, as you can see you have more than just 2 options :)
Of course, this doesn't apply to sessions only, the same goes for getting the request data, getting DB connection, and so much more.
(Also, I think you don't have the real-time facades in 5.3 yet)
Laravel Documentation
According to the Laravel Docs - https://laravel.com/docs/5.3/session - there is 'little practical difference between using the session via an HTTP request instance versus using the global session helper' and that both are testable.
->assertSessionHas($key, $value = null);
Laravel Up & Running - Matt Stauffer
In his book (page 320-), Matt talks through the different ways available to access session information:
Using the Session facade
session()->get('user_id');
Using the session() method on any given Illuminate Request object
Route::get('dashboard', function(Request $request) {
$request->session()->get('user_id');
});
Inject an instance of Illuminate\Session\Store
Route::get('dashboard', function(Illuminate\Session\Store $session) {
return $session->get('user_id');
});
Using the global session() helper
$value = session()->get('key);
$value = session('key);
His final comment is: If you're new to Laravel and not sure which to use, I'd recommend using the global helper.
So, I wouldn't worry about the differences and just go with what 'feels right' for you. If you have no preference either way, go with Matt Stauffer's recommendation.
Ultimately, the way that you normally use the two options, there is no practical difference between $request->session() and session(). However, they do not technically return the same objects.
session() will return the SessionManager. $request->session() will return the session Store.
The Store is actually the object that contains the session data.
The SessionManager is the object that manages the available session Stores. Most applications will only ever use one session store (the default one).
The reason why they seem to act as the same object is that when you call a method on the SessionManager that doesn't exist, it forwards that method call to the default session Store.
So, in your example, you use the exists() method. This method does not exist on the SessionManager. So, if you were to call session()->exists('user_id'), it would forward that call down to the default session Store, and it would be equivalent to calling $request->session()->exists('user_id').
One could argue that directly using $request->session() is more appropriate when attempting to access the session data, since that is what is returned, and doesn't require the additional forwarding function call. However, it is up to you to weigh the pros and cons to determine which method to use.
$request->session() and session() both are same thing.
There are two primary ways of working with session data in Laravel: the global function in session() helper and via a $request instance.
you can use it like this
public function testMyMethod(Request $request){
//$userExist = $request->session()->exists('user_id');
$userExist = $request->session()->has('user_id');
}
Actually native PHP session is a ready solution versus a better implementation from Laravel and Symfony that had put more thought into it. Read the explanation at Symfony Session configuration manual entry and you will understand i think. So there's a difference, but in the way it is thought and implemented. From the point of view from performance i think there isn't much. I will let you take your conclusions. Another entry that helps is at PHP manual
I have a route group with 6 routes inside it. I check the parameters on every route against the database.
What's the best way to achieve this? Build a class for it?
When working with a database, it really depends on how much you will be using it. Slim has no database integration, so you could access the database by either using basic php or using a ORM tool to assist you in talking with your database.
One orm that is quick and easy to use is idiorm http://idiorm.readthedocs.org/en/latest/index.html
There are other more robust things out there and it all depends on what you are trying to accomplish. Really, to give a "best" solution, we would need more information on the situation and also how you would quantify "best."
Try use Slim Middleware.
Add your check part as one middleware, and share a middleware for all routes. Then you will be happy.
Depending on your needs, you can also try using class instances as route callbacks.
Define a base class with all the database functionality and use "Class Controllers" available since version 2.4.0 (November 2013).
class Base {
// Define all your shared DB methods and properties here
}
Use child classes of your base class as controller class instances, as callbacks for your Slim app routes (and their parameters):
$app->get('/user/:id/', '\Base\User:find');
Getting an instance of $app in the callback class instance is easy enough:
class User extends \Base {
public function find($theUserId) {
// ...
// You can easily get access to $app here, too:
// $app = \Slim\Slim::getInstance();
}
}
I am having a controller IndexController.php in which action is something like this
class IndexController extends CustomControllerAction {
public function preDispatch() {
if (!$this->view->authenticated) {
$this->_redirect('/users/login');
}
}
public function indexemailAction() {
//somecode which calculates certain things
}
}
NOw,I need to call the action "indexmailAction" inside the IndexController.php with an independent php file
The php file is indextest.php
<?php
//Need to write some code to call indexmailAction in IndexController.php
?>
What should I write in this file ......
Thanks in advance
I know this is a few years old, and this may not be the intended use of the classes/functions, but I've found the following quite useful in isolated files that are called from the command line.
The problem this solves for me is that it eliminates spawning of Apache processes. The solution is great because I can access the some Controller/Action needed that I would from the URL.
In almost any ZF1 based app, you can copy your index file and keep everything the same and just comment out the following line.
$application->run();
Anything below this line you can access with your autoloaders etc. It's crude, but it works. Unfortunately, you'll soon find yourself with limited access to a lot of the files your application has, and the feeling the only way you can access the files needed is through a Controller/Action.
Instead, I use the following in a new file below $application->bootstrap() ( still removing the $application->run() ):
$front = Zend_Controller_Front::getInstance();
// You can put more here if you use non-default modules
$front->setControllerDirectory(array(
'default' => APPLICATION_PATH.'/controllers'
));
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setNeverRender(true);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
$req = new Zend_Controller_Request_Http("http://anydomain.tld/controller/action");
// Example just to see how this can be extended
$req->setParam("someVar", "someValue");
$front->setRequest($req);
$front->dispatch();
In the end you have a isolated PHP file that bootstraps everything the same as your main index.php for the web, but you can manually trigger a controller/action as needed, giving you easier access to the rest of the files with how ZF1 intended you to access them.
Controllers are designed to be used in an MVC, not by scripts. Your controller should assemble request variables, direct them to models and return an HTTP response of some sort. Your scripts should act directly on the models instead.
Anyhow, if you insist, you can instantiate a controller class and call methods just like any other class as long as you inject any dependencies that the MVC would have.
If you want logic used in multiple places in your actions, then it should go in an action helper or if very generic code, then in a custom library (/library/custom/)
NB: The authentication would be better suited in a plugin rather than the pre-dispatch method in every controller.
You should not have to call a controller action for this, your logic should reside in your models. Then you can create a new instance of your model and invoke the appropriate methods. example :
require_once '/path/to/mymodel.php';
$mymodel = new Mymodel();
$data = $mymodele->fetchAll();
PS: Maybe you should think of creating a restful api to handle calls from outside your application
UPDATE:
ok, I see now what you need, The best way to achieve it is to call a url instead of a file (e.g. website.com/emails/send), if you are worried about security you can use some preshared key to make sure the request comes from you, send it with the request and check if it's correct in your action.
I am trying to use a custom class in cakephp. Initially I had created a vendor class which works fine but I can't use other cakephp components.
To use built in components like $this->Text, I can create a custom component but the constructor requires a argument which is a json object returned from an API and I need to keep initializing in a loop
//The constructor for the class
function __construct($objValue) {
$this->messageId = $objValue['id'];
Is using a component suitable for this purpose?
you don't need to create a component here if you don't need it in the controller scope.
also you don't need to make it a vendor class (which is third party stuff).
cake offers you a way out: Libs in APP/Lib
You can use them anywhere anytime.
App::uses('MyClassName', 'Lib');
$MyClass = new MyClassName();
You might even want to create a package in Lib itself - e.g. "Lib/Utility":
App::uses('MyClassName', 'Utility');
without knowing any more about what exactly this custom class does, it is difficult to be any more specific here.
I'm building a small framework that I can use for repeated mundane stuff on future small projects.
I'm stuck on the best way to access libraries from inside a controller. I originally implemented a system similar to CodeIgniter's whereby my main controller class is basically a super object and loads all the classes into class variables which are then accessed by extending the controller and doing like $this->class->method()
I find that a little ugly, though. So I thought of just loading each class individually on a per-use basis in each controller method.
What's the best (cleanest) way of doing this?
To only ever have one instance of each class, you could create a simple service container.
class ServiceContainer
{
protected $services;
public function get($className)
{
if (!array_key_exists($className, $this->services)) {
$this->services[$className] = new $className;
}
return $this->services[$className]
}
}
Then create one ServiceContainer instance per application. Inject the container into all of your controllers and use
public function someAction()
{
$this->container->get('Mailer')->send($email_data);
}
Simple example, and obviously needs a lot of work to make useable (for instance autoloading needed and handling of file paths for ease of use, or easier way to add services without getting them, etc).
I dont like the way CodeIgniter does it. Its never seemed right to me. I favor an auto loading class pushed onto the spl_autoload stack. And then just calling the class as normal like:
$class = new SomeClass();
PHP provides autoload functionality with SPL and spl_autoload (and related functions). You can register a custom autoloader for your library code.
For the shared functionality handled by your application, have you considered the Front Controller design pattern?