Fatal error: Access level to Database::__construct() must be public (as in class PDO) in C:\xampp\htdocs\VT\Learnable\OOP-PHP\spbooks-PHPPRO1-ae9bb56\spbooks-PHPPRO1-ae9bb56\chapter_04\Ping\Singleton.php on line 30
getting this when in Singleton Design Pattern (1st DP in Lorna book (SITEPOINT) ch.4-DP “PHP Master: Write Cutting-edge Code”)
I HAVE BELOW - NOT GETTING but SUCCESS RUN WHEN public function __construct() (book says private)
private function __construct()
{
// Call the PDO constructor
parent::__construct(APP_DB_DSN, APP_DB_USER, APP_DB_PASSWORD);
}
included code from ch.2-db in this example
<?php
require("Singleton.php");
try {
$db_conn = Database::getInstance();
} catch (PDOException $e) {
echo "Could not connect to database";
exit;
}
/*
try {
$db_conn = new PDO('mysql:host=localhost;dbname=recipes', 'root', '');
} catch (PDOException $e) {
echo "Could not connect to database";
exit;
}
*/
try {
// start the transaction
$db_conn->beginTransaction();
$db_conn->exec('UPDATE categories SET id=99 WHERE name = "Pudding"');
$db_conn->exec('UPDATE recipes SET category_id=99 WHERE category_id=19');
// we made it!
$db_conn->commit();
echo "done";
} catch (PDOException $e) {
$db_conn->rollBack();
echo "Something went wrong: " . $e->getMessage();
} catch (Exception $e) {
$db_conn->rollBack();
echo "Something went wrong: " . $e->getMessage();
}
?>
The problem with the code here is that the PDO constructor is public, so any class extending PDO must also have it’s constructor public.
So there is no way you can extend PDO this way. The only thing you could do is instantiate a PDO instance in the constructor of your own class, like so
<?php
class MyClass
{
private $pdo;
private static $instance;
private function __construct()
{
$this->pdo = new PDO(/* params here */);
}
public static function getInstance()
{
if (null === self::$instance)
{
$self::instance = new self();
}
return self::$Instance;
}
/**
* Just an example method to show
* how to interact with the PDO instance
*/
public function queryAndFetch($query)
{
$stmt = $this->pdo->query($query);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
Of course you’d have to supply the correct parameters for PDO etc.
I think the OP’s problem is about private methods. Singletons usually use private constructors, but the assumption here is that you do not have an inheritance hierarchy. If inheritance is involved, you need to change your constructors into protected methods, so that your child class can call parent constructors. And of course there is absolutely NO requirement for constructors to be public, even in PHP 5.6.
I was wrong. A private constructor can be used when accessing methods using the scope resolution operator :: such as in the case with the singleton pattern. A private constructor will result in a fatal error when attempting to create an instance of the class using the new keyword. That may be desired behavior if you intend to use the DB class only as a singleton.
Fatal error: Access level to Database::__construct() must be public (as in class PDO) in C:\xampp\htdocs\VT\Learnable\OOP-PHP\spbooks-PHPPRO1-ae9bb56\spbooks-PHPPRO1-ae9bb56\chapter_04\Ping\Singleton\Singleton.php on line 31
private or protected give error
public - not Error
const APP_DB_DSN = "mysql:host=localhost;dbname=recipes";
const APP_DB_USER = "root";
const APP_DB_PASSWORD = "";
class Database extends PDO {
// A static variable to hold our single instance
private static $_instance = null;
// Make the constructor private to ensure singleton private protected - error
public function __construct() // not error getting with public
{
// Call the PDO constructor
parent::__construct(APP_DB_DSN, APP_DB_USER, APP_DB_PASSWORD);
}
// A method to get our singleton instance
public static function getInstance()
{
if (!(self::$_instance instanceof Database)) {
self::$_instance = new Database();
}
return self::$_instance;
}
}
?>
Same error, since that is not the problem. The problem is that PDO has a public constructor, so every class that extends it must also have a public constructor, like I already said in post #5 of this thread.