Laravel 4: dynamically load a class from a row in a database

I wish I knew how to search for this question / phrase in a more appropriate way. This made it difficult to find previous questions; bear with me if it's a duplicate.

See update / edit at the bottom of this post.

Background / what I'm trying to do:

I have a url that looks something like this:

http://myapp.com/calculate/ $fileID / $calculateID

$fileID and $calculateID are the keys that I use to track the data set and something that I call "calculation". Essentially, this URL says that execute $calculateID for the data in $fileID .

I go to my database (mongo) and ask for the php or sring class name or file path or what $calculateID matches for you. For example, sake can say that the table looks like this:

  +-----+-------------------+ | _id | phpFile | +-----+-------------------+ | 1 | basicCalcs.php | | 2 | advancedCalcs.php | | 3 | summaryCalcs.php | +-----+-------------------+ 

Note. it is safe to assume that every file in the phpFile column has a common interface / set of public methods.

Example:

http://myapp.com/calculate/23/2

will go to the database, receive data from set 23 , and then load the functions in advancedCalcs.php . After loading advancedCalcs.php function inside will receive data. From there, a set of calculations and transformations is performed on the data.

My question

My question is what is a “laravel 4 friendly” way to dynamically load advancedCalcs.php and feed data into a set of methods? Is there a way to lazily load this type of thing. Currently, I only know about the very complex require_once() method. I would really like to avoid this, since I am convinced that laravel 4 has the functionality to dynamically load the base class and connect it to a common interface.

EDIT 1

Thanks to Antonio Carlos Ribeiro, I was able to make some progress.

After running the dump-autoload vendor/composer/autoload_classmap.php there are several new entries in my vendor/composer/autoload_classmap.php file 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 similar to the sample below, I can instantiate the basicCalcs class:

 $className = "AppName\\Calc\\basicCalcs"; $instance = new $className; var_dump($instance); 

If 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 to create an alias similar to the AnalyzeController element in autoload_classmap.php rather than refer to basicCalcs.php with a full namespace?

+4
source share
2 answers

Add your library folder to your composer.json autoloader:

 "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 auto-loaded classes:

 composer dump-autoload 

If you want to be sure that this worked, check if your classes are loaded by opening the file

 vendor/composer/autoload_classmap.php 

To create them dynamically, it is best to have this as table class names:

 +-----+-------------------+-------------------+ | _id | phpFile | namespace | +-----+-------------------+-------------------+ | 1 | basicCalcs | Reporter\Calc\ | | 2 | advancedCalcs | Reporter\Calc\ | | 3 | summaryCalcs | Reporter\Calc\ | +-----+-------------------+-------------------+ 

Then you just need 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 assume your calculators are:

 class basicCalcs { public function calculate($calculateID) { return performCalculation( $calculateID ); /// something like this } } 

And your router somehow reminds

 Route::get('/calculate/{fileID}/{calculateID}', array('as'=>'calculate', 'uses'=>' CalculateController@calculate ')); 
+5
source

In Laravel4 , the composer.json file answers for this, the following 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" } 

Pay attention to the autoload section, where classmap used to tell Laravel4 which folders it should load classes from, and which file should be loaded. For example, "app/controllers", will be used to download all classes from the app/controllers folder, and "app/tests/TestCase.php" will make Laravel4 automatically load the TestCase.php class from app/tests/ . So add the library folder to the classmap section. After you added the path to the folder in the autoload -> classmap , you need to run

 composer dumpautoload // or composer dump-autoload 

from the command line.

+1
source

Source: https://habr.com/ru/post/1487777/


All Articles