What steps it takes to add GitHub repo to Laravel application? - php

I would like to use following GitHub repo in my Laravel application:
https://github.com/khanamiryan/php-qrcode-detector-decoder
It doesn't have composer set up nor it can be found from Packagist. I tried to use regular php_require but it tells me "Class 'App\Http\Controllers\QrReader' not found".
Using php_require feels wrong anyways. What is the correct way to handle situation like this?

Create a new directory in your app root
mkdir third-party
cd third-party
Clone the repo
git clone https://github.com/khanamiryan/php-qrcode-detector-decoder
Edit your composer.json file and add it to the classmap:
"classmap": [
"database",
"third-party/php-qrcode-detector-decoder"
],
Update class maps:
composer dumpautoload
And you should see in your vendor/composer/autoload_classmap.php
'Zxing\\Binarizer' => $baseDir . '/third-party/php-qrcode-detector-decoder/lib/Binarizer.php',
'Zxing\\BinaryBitmap' => $baseDir . '/third-party/php-qrcode-detector-decoder/lib/BinaryBitmap.php',
...
Then you just have to use it:
use Zxing\Reader;

I think the major class is QrReader(). You can use this class as controller class but you need to extend the controller class and fix imports. You can import this class as third party class on your laravel controller too.
Do you need to use QrReader() class?
Then just put all the library files App\Libraries and the main class in App\classes. Or you can do in our own way too. But follow the following
1) Manage namespaces
2) import the class to your controller by using
use App\classes\QrReader
Finally, you will have access to all the methods defined in the imported class. But in you main class you need to correct the path and dependencies of libraries files.
You can try this tutorial too:
How to use external classes
You can read the discussion here (Nice)
Best way to import third party classes

Because this github project does not have a composer.json file, I don't think you can use it with composer.
However, you could branch the repo, make your own copy, and add a composer file to it. Then you'd be able to add it to your main project's composer.json file:
{
"repositories": [
{
"type": "git",
"url": "https://github.com/your-git-account/php-qrcode-detector-decoder"
}
],
"require": {
"your-git-account/php-qrcode-detector-decoder": "dev-master"
}
Hope this helps!
(Source https://getcomposer.org/doc/05-repositories.md#loading-a-package-from-a-vcs-repository)

Related

Autoloading PHP file in composer package

I'm trying to create a composer package that also contains src/functions.php with some general functions. I have the following in composer.json to make it autoload:
"autoload": {
"files": ["src/functions.php"]
}
When I import this package into a project it will try to load src/functions.php in the current project (local) in stead of the imported package. Is there a way to ensure the correct file is loaded when imported (./vendor/bla/src/functions.php)?
Autoloading is not for loading everything. If src/functions.php contains class just ensure it's properly namespaced and I see no reason why autoloader would pick your local class instead of package's. If you are using the same namespace for the package and for code in your project then basically you should stop doing so.
If src/functions.php is just bunch of functions, then I strognly suggest refactoring the code and wrap them in properly namespaced class. You can make your functions static methods so basically not much would change from usage perspective.
EDIT
Once you finish refactoring, change your composer.json from what you shown in question to:
"autoload": {
"classmap": ["src/"]
}

Composer doesn't autoload packages

I'm currently developing a framework but I couldn't figure out how am I going to set autoloading. First I created a package with sample class and composer.json. I've autoloaded that sample class by:
"autoload": {
"classmap": [
"libs/"
]
}
I've checked /vendor/mypackage/vendor/composer/autoload_classmap.php and confirmed that package's autoloader is working fine. But the problem is I can't reach that package's class from main app unless I directly include that package's autoload.php.
UPDATE
/vendor/foo/mypackage/composer.json
"autoload": {
"psr-4": {
"Http\\": "libs/"
}
}
/vendor/foo/mypackage/libs/Request.php
namespace Http;
class Request {}
First of all, it's often better to use psr-0 or psr-4 autoloading config. With the classmap, you have to redump the autoloader each time you add a new class or rename one.
You always need to include the Composer autoloader by using require 'vendor/autoload.php';. The best place to add such require statement is in your front controller file.
Solved it by myself. I just had to reinstall package whenever I change pacakge's composer.json.

Including my class in a Laravel 5 Project

I made a class in php with some helper methods that parse HTML files.
I'd like to use this class in my Laravel project, but I'm new to Laravel and it's not clear how to add a simple class to a Laravel 5 project.
Is this possible? Or do I need to go to all the trouble of creating a composer package for my class, hosting it somewhere, and then require it in my composer.json file. That seems like a lot of work for including a simple PHP class, and I'm hoping there's an easier way.
As it stands right now there's not a great/easy way to do this in Laravel 5 (possibly by design). The two approaches you can take are
Create a new class in the App namespace
By default Laravel 5.0 looks for App\ prefixed classes in the app/ folder, so something like this should work
#File: app/Helpers/Myclass.php
<?php
namespace App\Helpers;
class Myclass
{
}
and then create your class with
$object = new App\Helpers\Myclass;
This approach, however, relies on you creating classes in the App\ namespace, and there's some ambiguity around if the App\ namespace is owned by Laravel, or is owned by the developer of the application.
Create your own Namespace and Register as PSR-4 autoloader
A better, but more complicated, approach would be to create classes in your own namespace, and then tell Laravel about this namespace by registering a new PSR autoloader.
First, you'd create the class definition
#File: application-lib/Myclass.php
<?php
namespace Pulsestorm;
class Myclass
{
}
Notice we've created a new folder off the root folder to hold our classes named application-lib. You could name this folder anything you like, because in the next step, you're going to add a section to your composer.json file's autoloader section
#File: composer.json
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Pulsestorm\\": "application-lib/"
}
},
The section we've added is this
"Pulsestorm\\": "application-lib/"
The key to the object (Pulsestorm\) is your namespace. The value (application-lib) is the folder where composer should look for class definition files with the specified namespace.
Once you've added this to composer.json, you'll need to tell Composer to regenerate it's autoload cache files with the dumpautoload command
$ composer dumpautoload
Generating autoload files
After doing the above, you should be able to instantiate your class with
$object = new Pulsestorm\Myclass;
The "real" right way to do this would be to create a generic composer package for your helper class, and then require that composer package into your laravel project. That may, however, be more work than you care to take on for a simple library helper.
If your class is generic enough to use it in other projects, the best way is to release it as a package.
Here's how you create packages with Laravel 5: http://laravel.com/docs/5.0/packages

Adding namespace to imported third-party package in Composer

I am importing a third-party package into my project using composer.
The composer.json of the package autoloads its classes using "classmap":
{
...
"name"=>"vendor/project",
...
"require": {
"php": ">=5.2.0"
},
"type": "library",
"include-path":["src/"],
"classmap": [
"src/path/to/lib1",
"src/path/to/lib2"
]
...
}
My project composer.json pulls the package in using "require".
{
...
"require": {
"vendor/project": "m.n.*",
}
...
}
I'd like to add a namespace that can prefix all the classes of that package when I use it in my project, can I do this in composer?
I am aware I can use autoload at the level of my project, but presumably these classes don't need loading again and where do I point it?
You cannot add a namespace to a project without editing every individual file in the project and adding a namespace .. declaration at its top. This is likely infeasible.
If you namespace your own code, there should be no possible problem of a name clash.
If the library clashes with yet another non-namespaced third party library which you also cannot feasibly namespace, then you're in trouble. Unless this is the case, there's no real reason to worry about it.
If composer's definition is set up properly, all you should need to do is simply use the class:
$foo = new \VendorClass;
Composer's autoloading will take care of loading the class, a missing namespace is of no concern (see above).

Own project via composer

I've got some libraries loaded through composer, and I'm wondering if it's possible to add my own library in the /vendor map, and then to have the composer autoloader load it? The structure would be something like /vendor/mylibrary/ and then a namespace mylibrary.
Would this be possible? Also would it be possible to add a different map to the composer autoloader? Like for example /app/src/ and then to have it load all the classes in that folder? Or do I have to make my own loader for that?
Thanks
Reading the composer documentation:
You can even add your own code to the autoloader by adding an autoload field to composer.json.
{
"autoload": {
"psr-0": {"Acme": "src/"}
}
}
Composer will register a PSR-0 autoloader for the Acme namespace.
You define a mapping from namespaces to directories. The src directory would be in your project root, on the same level as vendor directory is. An example filename would be src/Acme/Foo.php containing an Acme\Foo class.
After adding the autoload field, you have to re-run install to
re-generate the vendor/autoload.php file.
So basically, you just need to follow PSR-0, and tell composer where to find your library, by adding that line to your composer.json
Yes.You can achieve it. Configure your composer.json file as following:
{
"autoload": {
"classmap": [ "classes" ]
}
Here classes is the name of the directory where you have all your application related classes.Vendor related class should be auto detected as well. Just add the following line to achieve both at the same time:
require 'vendor/autoload.php';
And you can use the namesapce to reference your class like the following:
use classes\Model\Article;
Yes, of course it is possible to add own libraries and you should feel highly encouraged to do so. If your library is available publicly, you can simply register it at packagist.org. If not, it's a bit more complicated, but not impossible.
If your project does not follow the PSR-0 standard, composer will create a classmap for you. A custom autoloader is not supported.
I'd recommend you to read the (really excellent) documentation about all this and come back, if you're running into problems.
http://getcomposer.org/doc/

Categories