2

Suddenly, I cant dynamically instantiate a class. I can instantiate it if I call it directly, but calling it with a variable won't work. Here's whats not working:

    $database_class = 'MysqlConnection';

    $class = new MysqlConnection();
    $other_class = new $database_class();

The first instantiation, making $class, works fine. The second, making $other_class, fails and gives the following error:

PHP Fatal error: Class 'MysqlConnection' not found in /pronounce-php/src/Database/Connect.php on line 47

What am I doing wrong here? Heres the whole file if it helps:

<?php

namespace PronouncePHP\Database;

use Symfony\Component\Console\Output\OutputInterface;
use PronouncePHP\Database\Connection\MysqlConnection;

class Connect
{
    private $config;

    /**
     * Construct
     *
     * @return void
    */
    public function __construct()
    {
        $this->config = include('config.php');
    }

    /**
     * Get database connection
     *
     * @return Connection
    */
    public function getDatabaseConnection($output)
    {
        $database_type = $this->getDatabaseType($output);

        $database_class = $this->makeConnectionClass($database_type);

        $connection_information = $this->getConnectionInformation($database_type);

        // if (!class_exists($database_class))
        // {
        //     $output->writeln("<error>Database type not found!</error>");
        //     $output->writeln("<comment>Please ensure that the database type is specified and that it is supported</comment>");

        //     $GLOBALS['status'] = 1;

        //     exit();
        // }
        $database_class = "MysqlConnection";

        $class = new MysqlConnection();
        $other_class = new $database_class();
    }

    /**
     * Get database type specified in config file
     *
     * @return string
    */
    public function getDatabaseType($output)
    {
        $database_type = $this->config['database'];

        if (is_null($database_type))
        {
            $output->writeln("<error>No database type specified in config.php</error>");

            $GLOBALS['status'] = 1;

            return null;
        }

        return $database_type;
    }

    /**
     * Make class name for connection
     *
     * @return string $database_type
    */
    public function makeConnectionClass($database_type)
    {
        return ucfirst($database_type) . 'Connection';
    }

    /**
     * Get connection information for specified database type
     *
     * @return string $database_type
    */
    public function getConnectionInformation($database_type)
    {
        $information = $this->config['connections'][strtolower($database_type)];

        return $information;
    }
}
4
  • The first instantiation, making $class, works fine. - Are you sure? Commented Jun 24, 2015 at 6:28
  • Yes, it works fine. I found that if I use the full namespace path in the dynamic instantiation, it works as well. I wonder why it wont make a connection between the namespaced name and the 'use' statement... Commented Jun 24, 2015 at 6:35
  • The docs describe the behaviour just as you experienced it, so I guess its just how PHP handles it: PHP dynamic language features Commented Jun 24, 2015 at 6:55
  • 1
    side note : avoid using $_GLOBALS ; pass as function parameter / reference instead Commented Jun 24, 2015 at 7:14

1 Answer 1

5

The actual name of the class is PronouncePHP\Database\Connection\MysqlConnection. Since you've aliased it at the top of the file you can refer to it as MysqlConnection using literals. That's because literals are fixed in literal scope and name resolution is unambiguous.

However, strings in variables can come from anywhere any time and can hence not realistically be resolved against use statements. If you want to use the name as a string variable, you need to use the fully qualified name:

$database_class = 'PronouncePHP\Database\Connection\MysqlConnection';
Sign up to request clarification or add additional context in comments.

Comments

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.