Obiektowe zapytania PHP

0

Cześć, robię swój własny CMS. Po raz pierwszy chcę napisać skrypt nie strukturalnie tylko obiektowo. Napotkałem kilka problemów. Aktualnie pracuję nad aktualnościami. Może przedstawię najpierw kod z plików:

add_news.php:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Add news - CMS</title>
		<style>
		a { color: #000; text-decoration:none; }
		a:hover { color: #40b000; }
		nav { text-align:center; width: 50%; }
		nav li { display: inline; list-style-type:none; }
		textarea { width: 250px; height: 150px; }
		.name { font-size: 1.250em; text-align: center; }
		.content { text-align:center; margin: 120px; }

		</style>
	</head>

	<body>
		<div class="name">
			<p>Content management system</p>
		</div>
		<nav>
			<ul>
				<li><a href="page">Home page</a></li>
				<li><a href="add_news">Add news</a></li>
			</ul>
		</nav>
		<div class="content">
			<form action="add_news?action=add" method="post">
				<p>Enter your news topic:</p>
					<input type="text" name="topic" placeholder="topic"/>
				<p>Enter your news</p>
					<textarea type="text" name="news" placeholder="news"></textarea>
				<p><button type="submit" name="submit-news">Add news</button></p>
			</form>
		</div>
		<?php
			require_once 'sql_database.class.php';
			require_once 'add_news.class.php';
		?>
	</body>
</html>

sql_database.class.php:

<?php
	class SqlDatabase{
		function __construct() {
			try{
				$db = new PDO('mysql:host=localhost;dbname=cms', 'root', '',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
				}catch(PDOException $e){
					print_r('Connection database was broken!');
			}
		}
	}
	$ins = new SqlDatabase();
?>

add_news.class.php:

<?php
	class ValidateUrl{
		public function AddNews(){
			if (isset ($_GET['action']) && $_GET['action'] == 'add') {
				echo 'Youe news will by add!';
			}
		}
        public function ExampleQuery(){
            $query = $db->exec("INSERT INTO `CMS` SET `nick` = 'cos'");
            }
        }

	$ins = new ValidateUrl();
	$ins->AddNews();
        $ins->ExampleQuery();
?>

Chodzi mi o wykonanie prostego zapytania dodającego jakieś "śmieci" w kolumnie nick(tak jak wyżej). Chodzi o to, żebym załapał o co w tym chodzi. Normalnie gdybym pisał strukturalnie to nie było by problemów. Kilka takich skryptów już napisałem, próbuję napisać coś obiektowo.

I co? Otrzymuję jedną notyfikację oraz błąd krytyczny:

Notice: Undefined variable: db in C:\xampp\htdocs\CMS\add_news.class.php on line 9

Fatal error: Call to a member function exec() on null in C:\xampp\htdocs\CMS\add_news.class.php on line 9

Jak się z tym uporać. Z bazą danych wszystko się łączy poprawnie, bo testowałem. Prosiłbym też o spojrzenie na całość dotychczasowego kodu i doradzenie mi czy postępuję "zgodnie ze sztuką" oraz czy idę w dobrym kierunku?

0

Coś mi tu zasięg zmiennych śmierdzi :) nazewnictwo trochę też.

0

A jak to można naprawić? Możesz dać jakiś przykład?

0

Utworzyłeś obiekt SqlDatabase - przypisany do zmiennej $ins. Potem tworzysz drugi obiekt klasy ValidateUrl- przypisany do tej samej zmiennej i wewnątrz tej klasy odwołujesz się do nieistniejącej zmiennej $db; Poza tym w konstruktorze SqlDatabase masz zmienną $db - zrób z niej składnik klasy np public $db;

Zrób tak $sqlDb=new SqlDatabase(); A w klasie ValidateUrl dodaj konstruktor w którym np wstrzykniesz obiekt $sqlDb->db - do jakiejś prywatnej zmiennej. Możliwości jest bardzo dużo.

0

A w klasie ValidateUrl dodaj konstruktor w którym np wstrzykniesz obiekt $db do jakiejś prywatnej zmiennej.

Tego nie rozumiem do końca. Mój kod wygląda teraz tak, nie wiem czy o to chodziło:

add_news.class.php:

<?php
class ValidateUrl extends SqlDatabase{
	private $db;
	function __construct() {
		if (isset ($_GET['action']) && $_GET['action'] == 'add' ) {
			$query = $db->exec("INSERT INTO `CMS` SET `nick` = 'cos'");
			print 'Ok';
		}
	}
}
$ins = new ValidateUrl();

?>

sql_database.class.php:

<?php
	class SqlDatabase{
		function __construct() {
			try{
				$db = new PDO('mysql:host=localhost;dbname=cms', 'root', '',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
				}catch(PDOException $e){
					print_r('Connection database was broken!');
			}
		}
	}
	$db=new SqlDatabase();
?>

To powoduje takie same błędy. Nic się nie zmienia. Pewnie coś źle zrobiłem. Możesz mi podpowiedzieć co to takiego?

0

Takie coś może Ci zadziała, ale nie daje gwarancji, mogą być literówki.

<?php

class SqlDatabase
{

    private $_instance;

    public function __construct()
    {
        $db = null;

        try {
            $db = new PDO('mysql:host=localhost;dbname=cms', 'root', '', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
        } catch (PDOException $e) {
            print_r('Connection database was broken!');
        }
        $this->_instance = $db;
    }

    public function getInstance()
    {
        return $this->_instance;
    }

}

class ValidateUrl
{

    private $_dbHandler;

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

    public function AddNews()
    {
        if (isset($_GET['action']) && $_GET['action'] == 'add') {
            echo 'Youe news will be added!';
        }
    }

    public function ExampleQuery()
    {
        $query = $this->_dbHandler->exec("INSERT INTO `CMS` SET `nick` = 'cos'");
    }

}
$dbObject = new SqlDatabase();
$ins = new ValidateUrl($dbObject->getInstance());
$ins->AddNews();
$ins->ExampleQuery();
?>

0

Faktycznie błędy zniknęły lecz teraz nie są wykonywane zapytania do bazy danych.
var_dump($query); zwraca null.

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1); 

class ValidateUrl{
	 private $_dbHandler;
 
    public function __construct($db)
    {
        $this->_dbHandler = $db;
    }
 
    public function AddNews()
    {
        if (isset($_GET['action']) && $_GET['action'] == 'add') {
            echo 'Youe news will be added!';
        }
    }
 
    public function ExampleQuery()
    {
        $query = $this->_dbHandler->exec("INSERT INTO `cms` SET `nick` = 'cos'");
    }
 
}
$dbObject = new SqlDatabase();
$ins = new ValidateUrl($dbObject->getInstance());
$ins->AddNews();
$ins->ExampleQuery();

?>
<?php
class SqlDatabase{
	private $_instance;
	function __construct() {
		$db = null;
		try{
			$db = new PDO('mysql:host=localhost;dbname=cms', 'root', '',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
			}catch(PDOException $e){
			print_r('Connection database was broken!');
		}
		$this->_instance = $db;
	}
	public function getInstance(){
		return $this->_instance;
	}
}
$db=new SqlDatabase();
?>
0
public function ExampleQuery(){
	$query = $this->_dbHandler->exec("INSERT INTO `cms` SET `nick` = 'cos'");
	var_dump($query);
}

Zwraca to:

Youe news will be added!bool(false)

0

Insert - you're doing it wrong - > http://www.w3schools.com/sql/sql_insert.asp
a var_dump zwraca Ci tylko bool(false)- bo "Youe..." powstaje od echo którego używasz. Polecałbym poświęcić więcej czasu na poczytanie o tym jak działa OOP (niezależnie od języka)

0

Będę musiał coś poczytać. Ale dlaczego rekord nie dodaje się do bazy danych?

0

No rzeczywiście zapytanie było błędne. Mam teraz inny problem. Chciałbym wywołać errorInfo() gdy zapytanie będzie błędne. Dlaczego ten kod:

$query = $this->_dbHandler->exec("INSERT INTO `news` SET `nick` = 'cos'");
if (!$query->execute()){ 
	print_r($query->errorInfo());
}

Zwraca taki błąd:

Fatal error: Call to a member function execute() on integer in C:\xampp\htdocs\CMS\add_news.class.php on line 18

Linia 18 to jest to:

if (!$query->execute()){ 

Jak to można naprawić?

0

Przeczytaj dokumentację http://php.net/manual/en/pdo.exec.php - metoda exec zwraca Tobie integera, który u Ciebie jest przypisany do zmiennej $query. Z tej zmiennej chcesz wykonać metodę execute, której nigdzie wcześniej nie zauważyłem żebyś ją definiował. Nie można wywołać metody ze zmiennej która jest typu INT. Jak masz jakiś błąd... rób var_dump'a -> potem kierunek google -> wklejasz treść błędu i szukasz rozwiązania. Potem znowu.... jak masz błąd to var_dump... i tak w kółko. Błąd w tym przypadku miałeś prosty, nawet słownie opisany, jedyne czego nie robisz - to nie korzystasz z google.

0

Ja wiem tylko chodzi mi o zwracanie nazwy błędu gdy zapytanie będzie błędne. Wcześniej strukturalnie korzystałem z powyższego kodu ale teraz nie działa, gdy piszę obiektowo. Jak to zwrócić?

0

Nadal uważam, że nie próbujesz nawet poszukać sam rozwiązania. Proszę... tu masz przykład http://php.net/manual/en/pdo.errorinfo.php. Ja ze swojej strony poczekam, aż na serio coś zaczniesz szukać sam.

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