I wish i knew how to search for this question / phrase it more appropriately. This hampered my search for prior questions; bear with me if this is a duplicate.
See the update / edits at the bottom of this post
Background / what i'm trying to do:
I have a URL that looks a lot like this:
http://myapp.com/calculate/$fileID
/$calculateID
$fileID
and $calculateID
are keys that I use to keep track of a data set and something I call a 'calculation'. Essentially, that URL says perform $calculateID
on the data in $fileID
.
I go to my database (mongo) and ask for a php class name or sring or file path or what have you that matches $calculateID
. For example's sake let's say the table looks like this:
+-----+-------------------+
| _id | phpFile |
+-----+-------------------+
| 1 | basicCalcs.php |
| 2 | advancedCalcs.php |
| 3 | summaryCalcs.php |
+-----+-------------------+
Note: is is safe to assume that each file in the phpFile
column has a common interface / set of public methods.
Example:
http://myapp.com/calculate/23/2
would go to the database, get the data from set 23
and then load up the functions in advancedCalcs.php
. Once advancedCalcs.php
has been loaded, a function within will receive the data. From there, a set of calculations and transformations are performed on the data.
My question
My question is what is a 'laravel 4 friendly' way to dynamically load up advancedCalcs.php
and feed the data into a set of methods? Is there a way to lazy load this type of thing. Currently, i am only aware of the very unsophisticated require_once()
method. I would really like to avoid this as i am convinced that laravel 4 has functionality to dynamically load an underlying class and hook it up to a common interface.
EDIT 1
Thanks to Antonio Carlos Ribeiro, i was able to make some progress.
After running dump-autoload command, my vendor/composer/autoload_classmap.php
file has a few new entries that look like this:
'AnalyzeController' => $baseDir . '/app/controllers/AnalyzeController.php',
'AppName\\Calc\\CalcInterface' => $baseDir . '/app/calculators/CalcInterface.php',
'AppName\\Calc\\basicCalcs' => $baseDir . '/app/calculators/basicCalcs.php',
With code like the sample below, i can create an instance of the basicCalcs class:
$className = "AppName\\Calc\\basicCalcs";
$instance = new $className;
var_dump($instance);
Where the basicCalcs.php
file looks like this:
//PATH: /app/calculators/basicCalcs.php
<?php namespace Reporter\Calc;
class basicCalcs {
public function sayHi(){
echo("hello world! i am basicCalcs");
}
};
?>
Updated question:
How can i create an alias similar to the AnalyzeController
entry in autoload_classmap.php
rather than having to refer to basicCalcs.php
with a full namespace?
Add your library folder to your composer.json autoload:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/extended",
"app/calculators", <------- This is where you put all your calculators
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
Update your autoloaded classes:
composer dump-autoload
If you want to be sure it did worked, check if your classes are autoloaded opening the file
vendor/composer/autoload_classmap.php
To instantiate them dinamically you better have this as a table class names:
+-----+-------------------+-------------------+
| _id | phpFile | namespace |
+-----+-------------------+-------------------+
| 1 | basicCalcs | Reporter\Calc\ |
| 2 | advancedCalcs | Reporter\Calc\ |
| 3 | summaryCalcs | Reporter\Calc\ |
+-----+-------------------+-------------------+
Then you just have to use it
class CalculateController extends Controller {
public function calculate($fileID, $calculateID)
{
$file = phpFile::find($fileID);
$className = $file->namespace . $file->phpFile;
$calculator = new $className; //// <--- this thing will be autoloaded
return $calculator->calculate( $calculateID );
}
}
I'm assuming your calculators are all:
class basicCalcs {
public function calculate($calculateID)
{
return performCalculation( $calculateID ); /// something like this
}
}
And your router is somethink like
Route::get('/calculate/{fileID}/{calculateID}', array('as'=>'calculate', 'uses'=>'CalculateController@calculate'));
In Laravel4
the file composer.json
is responsible for this, following is an example
{
"require": {
"laravel/framework": "4.0.*"
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
"scripts": {
"post-update-cmd": "php artisan optimize"
},
"config": {
"preferred-install": "dist"
},
"minimum-stability": "dev"
}
Notice the autoload
section where classmap
is used to to tell laravel4
from which folders it should load classes and also which file should it load. For example, "app/controllers",
will be used to load all classes from the app/controllers
folder and "app/tests/TestCase.php"
will make Laravel4
to autoload the class TestCase.php
from app/tests/
folder. So, add your library folder in to the classmap
section. Once you have added your folder path in autoload -> classmap
section then you have to run
composer dumpautoload // or
composer dump-autoload
from the command line.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With