• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z OOP

VPS Starter Arubacloud
0 głosów
300 wizyt
pytanie zadane 19 października 2017 w PHP przez `Krzychuu Stary wyjadacz (13,940 p.)
edycja 19 października 2017 przez `Krzychuu

Witam

Zaczynam uczyć się obiektowego programowania w php, na początek chcę napisać prosty skrypt logowania, mam zrobione 2 klasy, AuthC i Config, w Config jest połączenie z bazą danych a w AuthC będzie logowanie, tylko mam problem jak to zrobić, próbowałem w AuthC dziedziczyć klasę Config ale nie mogę się do niej odwołać, w jaki sposób to zrobić, możecie od razu napisać czy dobrze zrobiłem robiąc 2 klasy, oraz gdy kliknę przycisk zaloguj się to w jaki sposób odpalić tą funkcję?

 

<?php
	
class Config 
{
	private $db_host = "localhost";
	private $db_user = "root";
	private $db_password = "";
	private $db_name = "login";
	
	public function __construct($db_name = "login")
	{
		$db_connect = new mysqli("$this->db_host", "$this->db_user", "$this->db_password", "$db_name");
		
		if($db_connect->connect_errno)
		{
			echo "Error connection: ".$db_connect->connect_errno;
		}
		else
		{
			return $db_connect;
		}
	}
}


?>

 

<?php
	
require_once('Config.php');
	
class AuthC extends Config
{
	$query = $db_connect->query("SELECT * FROM login");
	
	echo $query->num_rows;
}

$obj = new AuthC;

?>

gdy odpalam wyświetla się taki błąd:


Parse error: syntax error, unexpected '$query' (T_VARIABLE), expecting function (T_FUNCTION) or const (T_CONST) in 

 

1
komentarz 19 października 2017 przez Milesq Nałogowiec (32,020 p.)
masz klasę  AuthC ale nie ma w niej żadnej metody ani zmiennej

jest tylko fragment kodu którego  nie może być od razu w klasie najpierw zdefiniuj metodę

3 odpowiedzi

+1 głos
odpowiedź 19 października 2017 przez Else Stary wyjadacz (12,260 p.)

Nie możesz pisać bezpośrednio w klasie. Musisz stworzyć metodę w której będziesz sprawdzał zalogowanie stąd błąd. Ogólnie pomysł na 2 klasy nie jest zły zwłaszcza, że klasa config może być wielokrotnego użycia np gdy będziesz wybierał inne dane z bazy. 

Jak podpiąć:

  1. Wysyłasz z formularza dane postem do skryptu php.
  2. W skrypcie tworzysz obiekt klasy.
  3. Wywołujesz metodę którą musisz stworzyć z danymi z formularza. Metoda zwraca ci true lub false w zależności czy dane przeszły
komentarz 19 października 2017 przez `Krzychuu Stary wyjadacz (13,940 p.)
edycja 19 października 2017 przez `Krzychuu

tylko nie wiem jak wywołać tą metodę jak ktoś kliknie, czy od razu ustawić w pliku np. AuthC->login() i gdy będą dane to wykonać logowanie a gdy nie będzie to nic nie robić, tak?

EDIT:

zrobiłem coś takiego ale nadal wyskakuje błąd tym razem:

Fatal error: Uncaught Error: Undefined class constant 'Config'

 

<?php
	
require_once('Config.php');
	
class AuthC extends Config
{
	public function __construct($db_name = "login")
	{
		parent::Config;
	}
	
	public function login() 
	{
		$db_connect = $this->__construct();
		$query = $db_connect->query("SELECT * FROM login");
		echo $query->num_rows;
	}
}

$obj = new AuthC;
$obj->login();

?>

 

komentarz 19 października 2017 przez CenterPL Pasjonat (19,070 p.)

odwołanie parent::Config oznacza, że chcesz otrzymać STAŁĄ Config, która znajduje się w klasie Config. jeśli już to powinno być parent::__construct();

 

Lepiej zrób coś takiego (to nie dokładne rozwiązanie, jedynie zarys, chociaż wcale nie jakiś bardzo dobry)

<?php 

require_once('Config.php);

class AuthC
{
	private $config;
	
    public function __construct()
	{
		$this->config = new Config();
	}
	
	public function login()
	{
		$query = $this->config->query(...);
		echo $query->num_rows;
	}
}

$obj = new AuthC();
$obj->login();

?>

Można to ogólnie zrobić dużo lepiej :)

komentarz 19 października 2017 przez `Krzychuu Stary wyjadacz (13,940 p.)

a w jaki sposób można to lepiej zrobić?, mój pomysł z dziedziczeniem klasy nie był za dobry?

 

EDIT: zrobiłem tak jak napisałeś i wyświetla błąd, nawet po przekopiowaniu całego twojego kodu jest tak samo:

Fatal error: Uncaught Error: Call to undefined method Config::query()

komentarz 19 października 2017 przez CenterPL Pasjonat (19,070 p.)
Bo ten kod nie jest do kopiowania ;) przede wszystkim klasa Config nie udostępnia metody query więc nie ma się co dziwić.

Dziedziczenie należy stosować wtedy, gdy jedna klasa jest rozszerzeniem dla drugiej. Np Człowiek to rozszerzenie dla Ssaka. Albo Husky rozszerzeniem dla Psa. Czyli klasa dziedzicząca jest czymś, co uszczegóławia klasę rodzica.

Na Twoim miejscu, zrobiłbym sobie klasę załóżmy DbConnector, która po pierwsze przez konstruktor konfigurowałaby bazę danych, a po drugie umożliwiała pobranie danych rekordów. W klasie Auth w metodzie login wywoływałbym odpowiednią metodę klasy DbConnector. Kwestia też nazewnictwa, ale warto robić to dobrze.
komentarz 19 października 2017 przez `Krzychuu Stary wyjadacz (13,940 p.)

najpierw próbowałem zrobić sam gdy nie zadziałało zdecydowałem się na przekopiowanie :P, wcześniej próbowałem zrobić coś takiego:

<?php
	
class DBmanager {
	
	private $db_host = "localhost";
	private $db_user = "root";
	private $db_password = "";
	private $db_name;
	
	public function __construct($db_name = "test") 
	{
		$db_connect = new mysqli("$this->db_host", "$this->db_user", "$this->db_password", "$db_name");
		
		$db_connect->set_charset("utf8");
		
		if($db_connect->connect_errno) 
		{
			echo "Error Connection: ".$db_connect->connect_errno;
			exit();
		} 
		else 
		{
			return $db_connect;
		}	
	}
	
	public function __destruct()
	{
		$db_connect = $this->__construct();
		$db_connect->close();	
	}

	public function selectDB($selectquery) 
	{
		$db_connect = $this->__construct();
		$query = $db_connect->query($selectquery);
		
		$query->free();
	}
	
	public function updateDB($updatequery)
	{
		$db_connect = $this->__construct();
		$query = $db_connect->query($updatequery);
		
		if($query)
		{
			echo "This query was executed!";
		}
		else 
		{
			echo "This query not was executed!";
		}
		
	}
}

	$obj = new DBmanager();
	$obj->selectDB();
	$obj->updateDb();
			
?>

ale nie wiem czy takie coś się nadaje

+1 głos
odpowiedź 19 października 2017 przez Marchiew Dyskutant (7,690 p.)

Również się bawiłem w to co ty teraz i wykombinowałem coś takiego:

connect.php

abstract class Connect{
	private $_host = "localhost";
	private $_dbname = "obiektowosc";
	private $_root = "root";
	private $_password = "";
	
	protected $_connect;
	
	public function __construct() {
		try{
			$this -> _connect = new PDO("mysql:host=".$this -> _host.";dbname=".$this -> _dbname, $this -> _root, $this -> _password);
			$this -> _connect -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			$this -> _connect -> setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
		}
		catch(PDOException $e){
			echo "błąd połączenia z bazą: ". $e -> getMessage();
		}
	}
}

user.php

require_once "connect.php";

class User extends Connect {

	public function __construct(){
		parent::__construct();
	}

	function AddUser($name, $surname, $age) {

        $name = trim($name);
		$surname = trim($surname);
		$age = trim($age);

		try {
			$addUser = "
				INSERT INTO informacje (id, imie, nazwisko, wiek)
				VALUES (null, :name, :surname, :age)";

			$bind = $this -> _connect -> prepare($addUser);
			$bind -> bindValue(':name', $name, PDO::PARAM_STR);
			$bind -> bindValue(':surname', $surname, PDO::PARAM_STR);
			$bind -> bindValue(':age', $age, PDO::PARAM_INT);
			$bind -> execute();
			
			$bind = null;
			
			header("Location: ".$_SERVER["REQUEST_URI"]);
		}
		catch(PDOException $e) {
			echo "błąd dodania do bazy: ".$e -> getMessage();
		}
	}
    
	function ShowUsers() {
		try {
			$showUsers = "SELECT * FROM informacje";
			
			$view_users = $this -> _connect -> query($showUsers) -> fetchAll();
			
			var_dump( $view_users );
			
			require_once "plik.php";
		
			$this -> _connect = null;
		}
		catch(PDOException $e) {
			echo "nie można wyświetlić informacji: ". $e -> getMessage();
		}
	}

    function DeleteUser($id) {
        try {
			$deleteUser = "DELETE FROM informacje WHERE id = :id";
			$bind = $this -> _connect -> prepare($deleteUser);
			$bind -> bindValue(':id', $id, PDO::PARAM_STR);
			$bind -> execute();
			
			$bind = null;
		}
		catch(PDOException $e) {
			echo "błąd usuwania: ".$e -> getMessage();
		}
    }
/*
    function EditUser(){
        
    }
*/
}

if(!empty($_POST["imie"]) && !empty($_POST["nazwisko"]) && !empty($_POST["wiek"])) {
	
	$add_user = new User;
	$add_user -> AddUser($_POST["imie"], $_POST["nazwisko"], $_POST["wiek"]);
	$add_user = null;
}

if(isset($_GET["id_delete"]) && !empty($_GET["id_delete"])) {
	
	$url = $_SERVER["SCRIPT_NAME"];
	
	$detele_user = new User;
	$detele_user -> DeleteUser($_GET["id_delete"]);
	$detele_user = null;
	
	header("Location: ".$url);
}


$user = new User;
$user -> ShowUsers();
$user = null;

i plik.php (w rzeczywstości mam inaczej ale w locie pozmieniałem nazwy)

<!doctype html>
<html>
	<head>
		<title>Obiektowość</title>
		<meta charset="utf-8">
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>
	<body>
		<form method="post">
			<label>Imię: <input type="text" name="imie" /></label>
			<label>Nazwisko: <input type="text" name="nazwisko" /></label>
			<label>Wiek: <input type="text" name="wiek" /></label>
			<input type="submit" value="dodaj" />
		</form>
		
		<table>
		<?php foreach ($view_users as $row): ?>
			<tr>
				<td><?= $row -> id; ?></td>
				<td><?= $row -> imie; ?></td>
				<td><?= $row -> nazwisko; ?></td>
				<td><?= $row -> wiek; ?></td>
                <td><a href="?id_delete=<?= $row -> id; ?>">usuń</a></td>
			</tr>
		<?php endforeach; ?>
		
		</table>
	</body>
</html>

Zapewne też jest to fatalnie napisane, ale i tak jestem z tego zadowolony oraz mam nadzieję, że pomogę choć trochę :)

komentarz 19 października 2017 przez `Krzychuu Stary wyjadacz (13,940 p.)
dziękuje za chęci, ale ja nie szukam gotowego rozwiązania, chciałbym tylko rozwiązać problem z tym że nie mogę odwołać się do $db_connect :/
komentarz 19 października 2017 przez Marchiew Dyskutant (7,690 p.)
Ty robisz teraz w mysqli, a ja zrobiłem w pdo, także wykonanie inne, ale zamiar ten sam i można się na "czymś" wzorować niekoniecznie przepisując...

A może po prostu chciałem się pochwalić swoimi wypocinami? Kto to może wiedzieć haha
komentarz 19 października 2017 przez Marchiew Dyskutant (7,690 p.)

Na początek usuń te cudzysłowia z

$db_connect = new mysqli( $this->db_host, $this->db_user, $this->db_password, $db_name);

Zobacz czy działa. Jak nie to zrób z $db_connect:

protected $db_connect;

i odwołuj się poprzez $this -> db_connect ale to już wiesz doskonale. Jak nadal nie działa to dodaj do AuthC na początek:

public function __construct(){
	parent::__construct();
}

i do $db_connect odwołuj się wiesz jak. Jak nie będzie działać to daj znać.

Oczywiście całe query daj w metodę i wywołaj ją.

Kurcze, trudno się tak naprowadza kogoś jak się nie ma kodu odpalonego na własnym kompie... heh

komentarz 19 października 2017 przez `Krzychuu Stary wyjadacz (13,940 p.)
próbwałem tak zrobić wcześniej i nic :/
komentarz 19 października 2017 przez Marchiew Dyskutant (7,690 p.)

A tak próbowałeś, bo skopiowałem sobie twoją pierwszą wersję, poprawiłem i działa?

Config.php

<?php
     
class Config {
    private $db_host = "localhost";
    private $db_user = "root";
    private $db_password = "";
    private $db_name = "login";
	
	protected $db_connect;
     
    public function __construct() {
        $this -> db_connect = new mysqli( $this -> db_host, $this -> db_user, $this -> db_password, $this -> db_name );
         
        if($this -> db_connect -> connect_errno) {
            echo "Error connection: ".$db_connect->connect_errno;
        }
		else {
            return $this -> db_connect;
        }
    }
}
 
?>
<?php
     
require_once('Config.php');
     
class AuthC extends Config {
	
	public function __construct() {
		parent::__construct();
	}
	
	public function Show() {
		$query = $this -> db_connect -> query("SELECT * FROM login");
		 
		echo $query -> num_rows;
	}

}
 
$obj = new AuthC;
$obj -> Show();
 
?>

 

0 głosów
odpowiedź 19 października 2017 przez Boshi VIP (100,240 p.)
Po pierwsze to, konstuktor nie zwraca wartości - NIGDY!  a u ciebie warunkowo zwraca, a guzik, bo nic nie zwraca dlatego, nie możesz odwołać się do dbname w żaden sposób.

druga sprawa to to nawet obok obiektowości nie stało
komentarz 19 października 2017 przez `Krzychuu Stary wyjadacz (13,940 p.)
dzięki za rozjaśnienie, a co mógłbym poprawić żeby bliżej stało obiektowości?
komentarz 19 października 2017 przez Boshi VIP (100,240 p.)
Przepisać od nowa ;)
komentarz 19 października 2017 przez `Krzychuu Stary wyjadacz (13,940 p.)
a co zmienić?

Podobne pytania

0 głosów
1 odpowiedź 110 wizyt
pytanie zadane 7 stycznia 2019 w PHP przez TeslaX93 Gaduła (3,590 p.)
+1 głos
1 odpowiedź 177 wizyt
pytanie zadane 11 lutego 2022 w PHP przez ZnaQu Nowicjusz (130 p.)
0 głosów
0 odpowiedzi 97 wizyt
pytanie zadane 26 kwietnia 2020 w PHP przez creend Gaduła (4,700 p.)

92,454 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...