Slim framework shared code in routes - php

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();
}
}

Related

Using guzzle with CakePHP 2.x

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.

Autoload a simple DAO in Symfony2+Propel

I've been working on a project and I decided it'd be a good idea to have some sort of, like, DAO, but simplified.
Basically, the only thing I want from it (right now, at least) is to fetch me objects by model name and id. I wrote this very simple piece of code:
class DAO {
public static function get($className,$id) {
$queryName = $className."Query";
if (!class_exists($className) || !class_exists($queryName)) {
return false;
}
$q = $queryName::create()->filterByID($id)->find();
return $q;
}
}
However, I found myself stuck with the implementation. I guess I need to somehow autoload it so that it'll be able to check for the existence of the classes and so that I could use it anywhere inside my app, but I don't know how. Can anyone help me out? Or if there's a better way to do that, I'll appreciate any input.
What you're looking for is a Service.
Definition from the documentation:
Put simply, a Service is any PHP object that performs some sort of
"global" task. It's a purposefully-generic name used in computer
science to describe an object that's created for a specific purpose
(e.g. delivering emails). Each service is used throughout your
application whenever you need the specific functionality it provides.
Defining your class as a service is as simple as this:
app/config/config.yml
...
services:
my_dao:
class: Your\Bundle\DAO
...
Now you can access DAO in your controllers doing something like this:
$dao = $this->get('my_dao');
When you make this call, the Service Container will create an instance of your class and return it. There will always be at most one instance (singleton) and if it's never called, it won't even be instantiated.
I recommend reading the documentation.
Opinion
It seems like you're having trouble adapting to the Symfony way.
If you take a look at The Book you'll see that the Entity Manager in conjunction with your entity's Repository handle most of what DAO's traditionally did. In other words, there's really no need for your DAO class.
For example, fetching any object by id is as easy as:
$om->getRepository('YourBundle:YourModel')->find($id);
Anyway, if you're particularly fond of that approach, you may want to try this project.

Slim route mapping functions to classes

In fatfree framework,the route can do such things instead of writing lines of codes in callback function
$f3->route('GET /about','WebPage->display');
Where WebPage->display is class method and the class will be instanced before the method is invoked,I'm thinking of ways to do the same in slim framework but I don't have a clue while reading their doc on their official website,can you help me?
You are correct, as of the time of writing there is still nothing I can find in the docs about mapping routes to classes in the Slim Framework.
But the functionality does exist, since version 2.4.0 (November 2013). It's called "Class Controllers".
The link above provides a simple example, but I will provide one as well.
You can use classes as controller class instances, as callbacks for your Slim app routes (and their parameters):
$app->get('/user/:id/', '\User:find');
This will call the find method of the User class and pass the value if the :id parameter as the first parameter to the find method. So your callback class might look something like this:
class User {
public function find($theId) {
// Do something with $theId...
}
}
It is unfortunate that this useful Slim Framework feature has not found its way to the official documentation (yet).

How to access libraries inside a controller?

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?

Why does Codeigniter assume I want to create an instance of the class when using $this->load?

In Codeigniter, when we use $this->load('class_name') in the controller, CI will try to create an instance of the class/model using its constructor.
But sometimes, I don't actually need an instance from that class, I just want to call some static functions from it. Also, there is a big limitation with $this->load('class_name'), it does not allow me to pass parameters to the constructor (unless we extend or modify the core class of CI).
I think the $this->load('class_name') function should only do a require_once on the class php file for me, and let me freely do things (create instance/call static functions) with the class in the controller.
Should I simply ignore this function and use require_once or writing my own __autoload function to load up the classes? This way, I just feel strange because it seems I am not writing codes inside the CI box.
You can pass parameters to your constructor. See the "Passing Parameters When Initializing Your Class" section in the user guide.
I found CodeIgniter's object creation and loading to be very limiting. I want full control over my code, and little magic in the background. I have instead started using Doctrine's Class Loader. It's very lightweight and is essentially SPL autoloading (also a good alternative). You don't need the whole Doctrine shebang with ORM and all that stuff, just the ClassLoader. There's some configuration tinkering to get this right, but it works wonders.
With PHP 5.3 I now have namespaced classes in the Application directory. For instance I created a new class in the Tests directory: Application\Tests\SomeTest.php
That test could look something like this:
namespace Tests;
class SomeTest {
...
}
I would use this class in my code (controllers, views, helpers) by simply using the fully qualified namespace (i.e. $test = new \Tests\SomeTest) or a "use" statement at the top of my code (use \Tests\SomeTest as SomeTest).
In this way I intend to replace all libraries and models with OO namespaced variants. There are many benefits to this: fast autoloading with SPL, full IDE intellisense support for classes/methods (CodeIgniter is really bad for that), your code is more portable to other frameworks or projects.
That said, I still use a lot of the CodeIgniter engine. This basically means I have $CI =& get_instance() in most of my classes. It's still a work in progress and I think the main reason I need CI is for it's database access. If I can factor that out ... and use something like Dependency Injection, then I won't need CodeIgniter in my classes at all. I will simply be using it for it's MVC framework, and using it's methods occasionally in my controllers.
I know this goes above and beyond your question, but hopefully it's some food for though - and it helps me to get it in writing too.

Categories