[PHP] Använda ett objekt i en annan klass __construct

Permalänk
Inaktiv

[PHP] Använda ett objekt i en annan klass __construct

Hallå,
har lite problem med att jag vill använda mig av mitt databas objekt i en annan klass __construct funktion.

Så här laddar jag min databas klass och skapar objektet (ger inga felmeddelande):

require('database.php'); $Database = new Database(); try { $Database->connect(); } catch(Exception $e) { echo($e->getMessage()); } require('abstractActor.php');

När jag sedan försöker använda $Database i en annan klass (som skapas i abstractActor.php) så får jag felmeddelandet att $Database är odefinerad.

abstract class Actor { protected $Name; protected $Data; public function __construct($Name) { try { $Result = $Database->query('SELECT * FROM `Actors` WHERE `Name` = "'.(string) $Name.'"'); } catch(Exception $e) { echo($e->getMessage()); } } public function __toString() { return('Actor name: '.$this->Name); } }

Får endast det här felmeddelandet när jag använder klassen, om jag inte skapar ett objekt som använder klassen så får jag inga felmeddelande.

Tack i förhand!
/Havsmonstret

Permalänk
Medlem

Tjenare!

Vad jag kan se vid första anblick är att du i kontruktorn i din Actor-klass försöker använda $Database som ett objekt med funktioner.
Du behöver skapa en ny instans av din Databas-klass även där, då $Database inte verkar referera till något just nu.

Ex:

$Database = new Database(); $Result = $Database->query('SELECT * FROM `Actors` WHERE `Name` = "'.(string) $Name.'"');

EDIT:
Anledning till detta fel är att alla variabler existerar i olika "scopes" (typ rymder) och dina funktioner i klassen har sin egen variabelscope så enbart medlemsvariabler i klassen eller variabler du deklarerat i funktionen går att komma åt. (Finns även undantag med globala variabler och konstanter).

class Example { //medlemsvariabel i klassen private $_myMemberVar = 'foo'; public function myFunction() { //En vanlig variabel deklarerad i funktionen $myOtherVar = 'bar'; //Båda dessa funkar echo $this->_myMemberVar; echo $myOtherVar; } public function myOtherExample() { //Funkar inte då $myOtherVar inte existerar här, utan enbart i myFunction() echo $myOtherVar; //Men denna funkar eftersom den är deklarerad i klassen echo $this->_myMemberVar; } }

Visa signatur

PC: i7 3770k, Asus P8Z77-M PRO, 16GB @ 1600Mhz CL9, Gigabyte GTX670 OC, 120GB Intel 330
HTPC: i5 3450, ASRock Z77M mATX, 8GB @1600Mhz CL9, Gigabyte GTX670 OC, 160GB Intel 320
Server (Ubuntu 12.04): Pentium G2030 3Ghz, 4GB @ 1600Mhz, 160GB VelociRaptor, 4*1TB 7200RPM @ RaidZ

Permalänk
Inaktiv

Tack för att du tog dig tid men satt och kolla det precis och är som du säger, att den inte kan komma åt $Database i abstractActor klassen.
Det jag gjorde var att skickade vidare $Database som en referens. Skickar med koden om någon har liknande problem i framtiden:

public function __construct($DB = FALSE,$Actor,$Name,$Data,&$Database) { if($DB != FALSE) { try { $Result = $Database->query('SELECT * FROM `Actors` WHERE `Name` = "'.(string) $Name.'"'); echo('A new ' . $Result['Actor'] . ' actor named ' . $Result['Name'] . ' was created with the data: ' . $Result['Data'] . ' !'); } catch(Exception $e) { echo($e->getMessage()); } } else { $Result = array( 'Actor' => (string) $Actor, 'Name' => (string) $Name, 'Data' => (string) $Data ); echo('A new ' . $Result['Actor'] . ' actor named ' . $Result['Name'] . ' was created with the data: ' . $Result['Data'] . ' !'); } }

Sen skapar jag objektet såhär där $Database är det existerande databas objektet:

new DynamicActor(TRUE,0,'Ted','Data',$Database);

Permalänk
Medlem

Vore jag dig skulle jag titta lite på singeltonmönstret och använda det för att bygga en databasklass (och skulle då även se till att använda mig av PDO).

T.ex. något sånt här (ej testat):

abstract class DB { static private $instance; private $dbh; static public function getInstance() { if (!self::$instance instanceof DB) { self::$instance = new DB(); } return self::$instance; } private function __construct () { self::$dbh = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); } private function __destruct () { self::$dbh = null; } static public function query ($query) { return self::$dbh->query($query); // eller något, går att göra mycket fina saker med PDO } static public function prepareQuery ($query, $params) { return self::$dbh->prepare($query)->execute($params); } }

När du sedan vill använda databasklassen är det bara att köra DB::getInstance()->query($sql). Så slipper du hålla på att skapa massa databasobjekt så fort du ska arbeta med databasen.

La till länk till info om singeltonmöstret.
Visa signatur

WS: Antec P182B | FSP Aurum 500W | Asus P8Z77-V PRO | i5 3570k | 16GB DDR3 | Intel 320 80GB SSD | HDD 5TB | Asus Xonar DX | Arch Linux (x86_64) | Eizo EV2795
HTPC: Philips 50PUS8804, Kodi samt extern usb-disk
Server: Raspberry Pi 3 model B+ | 1GB RAM | HDD 750GB | Arch Linux (armv7h)

Permalänk
Medlem
Skrivet av '[vEX:

;11077504']Vore jag dig skulle jag titta lite på singeltonmönstret och använda det för att bygga en databasklass (och skulle då även se till att använda mig av PDO).

Jag tycker det är smartare att göra som han gör nu, att skicka med ett Database-objekt. Det blir ingen extra kod och han kan använda samma funktioner för att koppla upp sig mot olika databaser. De två sista funktionerna ska hursomhelst inte vara static.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Inaktiv

Tittade lite på Singelton och eftersom jag inte behöver mer än ett databas objekt så gjorde jag om funktionerna till Static.
Då behöver jag inte passera databas objektet till abstractActor heller utan kan köra Database::Query(); direkt.

Ska ta en titt på PDO också.