14

i want to create object of class base on string which come from URL parameter.

for example :

 http://localhost/CSWeb/api/search/Slideshare

in above URL Slideshare is parameter which get in apiController->indexAction.

slideshare.php class

<?php

namespace App\Http\API;

class slideshare 
{

    public function index()
    {
         return 'any data'; 

    }

}

apiController.php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Auth;
use App\Http\API\Slideshare;

class apiController extends Controller
{

    public function index($source)
    {
        $controller=  new $source;
        return $controller->index();
        // if i change code to  $controller=  new Slideshare; it works fine
    }

}

laravel error when i use parameter string to create class object

FatalErrorException in apiController.php line 17: Class 'Slideshare' not found

if i change code to

$controller=  new Slideshare; it works fine

Thank you in advance

1 Answer 1

48

When creating PHP objects with strings, you must provide the full qualified name of the class (a.k.a include the namespace). So, you should have something like this:

$className = 'App\\Http\\API\\' . $source;

$controller =  new $className;

return $controller->index();

Another way to do it, if you are sure that the class you want to instantiate lives in the same namespace as your code, you can use:

$className = __NAMESPACE__ . '\\' . $source;

$controller =  new $className;

return $controller->index();

A more elaborated way of achieving the same results is through the Factory Design Pattern. Basically you create a class that is responsible for instantiating elements, and you delegate the task of actually creating those objects to that class. Something along those lines:

class Factory {
  function __construct ( $namespace = '' ) {
     $this->namespace = $namespace;
  }

  public function make ( $source ) {
    $name = $this->namespace . '\\' . $source;

    if ( class_exists( $name ) ) {
      return new $name();
    }
  }
}


$factory = new Factory( __NAMESPACE__ );

$controller = $factory->make( $source );

The advantage of this approach is that the responsability of creating the objects now lies in the Factory, and if you ever need to change it, maybe allow for aliases, add some additional security measures, or any other thing, you just need to change that code in one place, but as long as the class signature remains, your code keeps working.

An interesting tutorial on factories: http://culttt.com/2014/03/19/factory-method-design-pattern/

Source: https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.new http://php.net/manual/en/language.namespaces.nsconstants.php

Sign up to request clarification or add additional context in comments.

6 Comments

Ah, there it is. +1. "If a string containing the name of a class is used with new, a new instance of that class will be created. If the class is in a namespace, its fully qualified name must be used when doing this."
@Scorch Thank you .Perfect answer it works fine . you save my day. have try to solve this issue from last 1 hour . Thank you again .
@ceejayoz is there other way to do same ?
@NishitMaheta Updated my answer. Not sure this is what you wanted.
@NishitMaheta Then you either need to manually create the mappings (the kind of aliases I was talking about in my answer) for the namespaces manually, or find out some pattern for the namespaces. Without knowing more of how the classes are structured, it's hard to suggest a solution. :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.