Instancja klasy i funkcja statyczna

0

Witaj,

mam problem z odwołaniem się do klasy. Pojawia się mi cały czas poniższy komunikat:

Fatal error: Using $this when not in object context

Wiem, że to jest problem z odwołaniem się do funkcji, ale za bardzo nie rozumiem dlaczego pojawia się ten błąd. Mam klase odpowiedzialną za poł. z bazą, wygląda ona tak:

	
	protected $db = '';

public function __construct() {
		try {
			$this->db = new PDO('mysql:host=' . DB_HOST . '; dbname=' . DB_NAME . ';', DB_USER, DB_PASS);
		} catch( PDOException $e ) {
			print_r( $e->getMessage() );
		}
	}

	public function database( $param ) {
......
	} 

I teraz z innej klasy chcę wywołać metodę database. Plik wygląda tak:

 
require_once('./DB.class.php');

class user{
	protected $db;

	public function __construct() {
		$this->db = new DB();
	}

	public static function signIn( $login, $pass ) {
		// $db = new databaseManager();
		$sql = '';
		$query = $this->db->database( $sql );

W tej wersji kodu pojawia mi się wspomniany komunikat, wiem, że on się pojawia jak się np. metodę statyczną wywołuje przez $this. Ale metoda "database" nie jest statyczna, więc powinienem korzystać z "this". Jednak w tym przypadku nie działa konstruktor. Nie wiem dlaczego. Czy możesz mi pojaśnić co robię źle?

PS. Jak w metodzie signIn odkomentuję $db i zmienię $query na "$query = $db->database(...);" to wszystko działa. Z tym, że nie chcę w każdej metodzie tworzyć instancji DB, bo chyba nie o to chodzi w OOP ;-)

0

masz klase statystyczna

    public static function signIn( $login, $pass ) {

a w niej nie możesz użyć $this-> zamiast $this-> użyj self::

0

Nie statystyczka tylko statyczna sorry*

0

Dzięki faktycznie. W statycznej nierozsądne było używanie "$this" :-) Ale to nie rozwiązało mojego problemu, teraz dostaję taki komunikat:

Fatal error: Call to a member function database() on a non-object in

O ile rozumiem, że wypluwa mi, że database nie jest obiektem to nie wiem jak się do niej odnieść.

Zastanawiam się czy w ogóle dobrze to robię. Chodzi mi o to, że przekazuję do metody statycznej login i hasło z niej wykonuję zapytanie do db i sprawdzam czy istnieje (metoda niestatyczna). Czy to jest poprawne rozwiązanie?

 public static function signIn( $login, $pass ) {
//			$o = new databaseManager();
		$sql = 'SELECT id, password FROM `users` WHERE login = "' . $login . '"';
		$query = self::$database->dbAction( $sql ); // w tej lini pokazuje, że jest powyższy błąd
0

Ja sie nie znam za bardzo ale może tak: zamyśl sobie o co ci chodzi. Powiedzmy, że chcesz mieć klasę która łączy sie z bazą i wykonuje zapytanie i zwraca wynik. Tak obmyślaną klasę mógłbyś dołączać do projektu i przekazywać sobie do niej zapytania. Taka klasa mogłaby wyglądać tak:

<?php

class Model_DB {
    
    public $objDB;
    
    public function __construct() {
        try {
            $this->objDB = new PDO('mysql:host=' . DB_HOST . '; dbname=' . DB_NAME . ';', DB_USER, DB_PASS);
        } catch( PDOException $e ) {
            print_r( $e->getMessage() );
        }
    }
    
    protected function select($select, $fetchAll = true){
        $query = $this->objDB->query($select);
        if($fetchAll === true)
            return $query->fetchAll();
        return $query->fetch();
    }
    
}

?>

Klasa powyżej łączy się na construktorze do bazy a potem za pomocą objDB (ja zawsze nazywam sobie objZmienna) wykonuje select i albo zwróci ci tablicę z kilkoma wynikami albo z jednym w zależności czy tasz $this->objDB->select($sql,true) czy $this->objDB->select($sql,false)

Teraz robisz sobie projekt i dodajesz drugą klasę jak widzę coś w stylu

<?php

class login extends Model_DB{
 
    public function signIn( $login, $pass ) {
        $sql = "SELECT id FROM users WHERE login = '".$login."' AND pass = '".$pass."';
        return $this->objDB->select( $sql );
    }

}

?>

Funkcja statyczna jest oczywiście szybsza i nie trzeba tworzyć instancji ale jak widzisz musisz tak zaprojektować ją by albo tworzyła instancję na potrzeby Twoje chwilowe albo nie używała ich. Drugim dobrym jak dla mnie rozwiązaniem jest by nie przekazywać parametrów do funkcji w stylu function name($par1, $par2, Par3 ...) tylko zrób:

<?php

$varParams = array(
    'login' => $login,
    'pass' => md5($pass),
);

$this->model->signIn($varParams);

?>

a w tedy w funkcjach masz całą tablice paramsów

<?
    public function signIn( $parParams ) {
        $sql = "SELECT id FROM users WHERE login = '".$parParams['login']."' AND pass = '".$parParams['pass']."';
        return $this->objDB->select( $sql );
    }
?>

Dodając 10 dodatkowych paramsów nie musisz zmieniać wtedy w funkcjach w pliku gdzie ja wywolujesz i tu gdzie jest jej ciało :D jak to brzmi hahaha. Ale jak mówiłem nie zam się za bardzo na tym całym php i kalsach

0

Nie sprawdzałem tego, ale wydaje mi się, że właściwość $db też musi być statyczna.
Ze względu na testy jednostkowe zastanów się, czy klasy statyczne są użyteczne - w testach jednostkowych jest z nimi problem, bo nie można ich zaślepiać. Dodatkowo wprowadzą powiązania między klasami, które trudniej śledzić. Proponuję byś obiekt dostępu do bazy przechowywał w kontrolerze aplikacji i stamtąd przekazywał go do obiektów, które z niego będą korzystały.
W Twoim projekcie właściwością obiektu klasy User jest obiekt dostępu do bazy danych, a przecież użytkowników rozróżniamy po loginach i hasłach, ich cechą nie jest baza danych. Proponuję byś tworzył obiekt klasy User i go przekazywał do klasy, która będzie potrafiła go zapisywać w bazie (lub jeszcze ogólniej w dowolnym repozytorium), wówczas klasa User będzie encją, a zarządca encji będzie odpowiedzialny za tworzenie, pobieranie danych i ustawianie ich w encji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1