Where to create a class of its own, and how to instantiate it later?

Asked

Viewed 5,592 times

16

I have a class of my own (i.e. external to the standard PHP and Laravel libraries) that makes some connections with equipment in my network and also need to create routines for email and SMS notifications.

For reference, this is the class:

<?php
/*****************************
 *
 * RouterOS PHP API class v1.5
 * Author: Denis Basta
 * Contributors:
 *    Nick Barnes
 *    Ben Menking (ben [at] infotechsc [dot] com)
 *    Jeremy Jefferson (http://jeremyj.com)
 *    Cristian Deluxe (djcristiandeluxe [at] gmail [dot] com)
 *
 * http://www.mikrotik.com
 * http://wiki.mikrotik.com/wiki/API_PHP_class
 *
 ******************************/

class routeros_api
{
    ...
}
?>

Question

Where to put the class files, and how to call it later from the application?

And if there is more than one viable option, what would be the best practices to keep the third-party code organised?

  • 1

    It is unclear what you are asking. Could you please edit the question and include more details? What can you already do and what’s missing? What points do you need help with? Good practice regarding what? What are these classes you already have? There is no generic answer, each class has a different way of using. Doubt is how to integrate the classes in Laravel?

  • I have this class for example: http://wiki.mikrotik.com/wiki/API_PHP_class And I need to use it in a project that is being developed in Laravel. The question is, where to put it and how to use it.

  • 2

    @Elizandropacheco in my opinion, now the question is already "responsive". Because if I understand correctly, you want to know what part of your folder structure you should put a new class (yours or third party) so that Laravel finds it [and, if there is more than one option, which one would be more appropriate], is that it? (P.S. I will try to suggest an edition to improve the shape - without touching the contents)

  • 1

    @Elizandro Pacheco your problem is with loading the? class into the right folder? does the framework follow any loading pattern (PSR-)? describe better what you have tried.

  • @lost I haven’t tried anything yet, I came to ask just to start the right way.

  • @mgibsonbr Exactly that!

  • @Elizandropacheco Take a look at this package, I use it to communicate with Routeros: https://packagist.org/packages/pear2/net_routeros can be installed via Composer so it will already be automatically loaded

  • also considers the options to use package, depending on what you are doing may be the best solution and can reuse in other projects.

Show 3 more comments

3 answers

9

I usually create a Library folder within /app, and add it to the autoload of Composer.json (autoload -> classmap node)

You can also, add in the autoload of Laravel itself, in the file /app/start/global.php

Link: https://github.com/laravel/laravel/blob/master/app/start/global.php#L14

Note that when choosing the second option, you will not need to run the dump-autoload of the Composer every time you create a class, or change the namespace and so on, unlike the first option.

Or, you can create a package and put its classes in the vendor folder/

As you can see, Laravel is very flexible in this part, it is to its own taste, there is no "cake recipe". What I can consider as "good practice", for your project may not fit, so it goes from your needs.

PS: When creating subfolders, don’t forget to use namespaces correctly for autoload to work.

  • I created the library folder and put the file ( routeros.php ) inside it. The class name is Routeros inside that file. At start/global.php I added the library folder but when I try to instantiate the class in the controller it returns the following error: Class 'Routeros' not found

  • Remember to put the class and file name according to the autoload pattern of PSR. Change the file name to Routeros.php

  • It worked perfect! Thanks @Brayan

  • If you choose to put the classmap of Composer you can also edit it manually so you don’t have to run an update every time you add a class. The archive is in /vendor/composer/autoload_classmap.php

4

For code directly related to the business rules of your application

I’m sorry to say that the PSR-0 is being substituído by PSR-4, which makes our life much easier when it comes to managing class directories, as it does not require you to create folders with the namespace name, which used to be confusing for most who were trying to start using PSR-0.

The PSR-4 is available to use if your Composer is up to date:

[sudo] composer self-update

Therefore, I advise you to use a pattern similar to:

"autoload": {

    "psr-4": {
        "Empresa\\Pacote\\": "app/Pacote/"
    }
},

Done this you just need to create the file Classe.php in:

app/Pacote/Classe.php

And not like what happened on PSR-0, if you wrote the same, you’d have to put in:

app/Pacote/Empresa/Pacote/Classe.php

And follow the normal namespace creation rules for your classes:

<?php 

namespace Empresa\Pacote;

class Classe extends Whatever {

}

Then just update the files autoloaders of the Composer:

composer dump-autoload -o

And he probably created the file

vendor/composer/autoload_psr4.php

With a line pointing to your folder, which will be after vasculhada if PHP needs to load any of the classes present there.

For third party code what you want to reuse

When it comes to third party code or your code that can be used in more than one application your ideal, in my opinion, is to create a Composer package.

It seems complicated, but it’s very simple, follow the steps:

1) Create a repository for your package on github or bitbucket.

2) Create a folder anywhere that doesn’t need to be linked to your app yet.

3) In it create a file Composer.json and in it you need to basically have:

{
    "name": "empresa/pacote",

    "description": "<descrição>",

    "keywords": ["palavra-chave1", "palavra-chave1"],

    "require": {
        "php": ">=5.3.7",
    },

    "autoload": {
        "psr-4": {
            "Empresa\\Pacote\\": "src/"
        }
    },

    "extra": {
            "component": "package",
            "frameworks": ["Laravel 4"],
            "versions": {
                    "0.8.0": "master"
            },
            "branch-alias": {
                    "dev-master": "0.8.0-dev"
            }
    },

    "minimum-stability": "dev"
}

3) Create the package source files within the folder src/. This folder name has become standard, but many people use something different, like lib/.

4) Upload your package to a git repository:

git init
git remote add <repositorio>
git commit -m "mensagem"
git push origin master

5) And finally add the package to your project’s Composer.json:

"require": {
    "empresa/pacote": "dev-master",
},

6) Since your package is not yet published in Packagist, you will need to let Composer know where his sources are, in case if your VCS is Github, you will do:

"repositories": [
    {
        "type": "vcs",
        "url":  "https://github.com/seunome/pacote.git"
    }
],

7) And just update Composer to see your new package being downloaded into your application:

composer update --prefer-source

I added the option prefer-source in order for Composer to download, in addition to the sources, also the directory .git, so that you can edit your package directly in your application directory and commit the changes without having to leave it.

I don’t know if it seemed complicated, but I guarantee it’s very easy.

  • Beautiful. Very good. At the beginning, in your first example, it wouldn’t be "psr-4": or instead of "psr-0":?

  • Yes, of course, I was speaking on PSR-4 and ended up writing 0...

2

With Laravel and Composer it’s very easy to work with your own classes.

If you organize your classes well with namespaces it is extremely easy to load them afterwards

I do so:

app/Meupacote/

app/Meupacote/Minhaclasse.php

namespace Meupacote;
class MinhaClasse{}

and in Composer.json you easily load them:

"autoload": {
    
    "psr-0": {
        "Meupacote": "app/"
    }
},

You can put your entire application there, such as models and controllers

app/Minhaapp/

app/Minhaapp/Controllers/

app/Minhaapp/Controllers/Homecontroller.php

"autoload": {
        
        "psr-0": {
            "Minhaapp": "app/"
        }
    },

Remember by doing so you should start importing the other classes since now you are working with namespace

namespace Minhaapp\Controllers;
use BaseController;
class HomeController extends BaseController{}

There will be no difficulty in configuring your routes

Route::get('/', 'Minhaapp\Controllers\HomeController@index');

Browser other questions tagged

You are not signed in. Login or sign up in order to post.