Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Połaczenie z bazą danych a insert
Forum PHP.pl > Forum > PHP > Object-oriented programming
marcwars
Witam
od paru dni próbuję przypomnieć sobie podstawy OOP tworząc prostego cmsa z funkcją dodawania artykułów.
Jednak wywala mi się błąd: No database selected. Do kodu włączyłem nowe funkcje mysqli, więc chyba tam jest błąd, niestety po godzinach ślęczenia, nie potrafię go znaleźć.

Formularz:

Kod
<html>
<body>
<form action="dzieki.php" method="post">
Autor: <input type="text" name="autor"><br /><br />
Tytuł: <input type="text" name="tytul"><br /><br />
Tekst: <input type="text" name="tekst"><br /><br />
<input type="submit" value="Dodaj">
</form>
</body>
</html>


klasy (class/DB_pt.class.php):

Kod
<?php

class DB {
    
    protected $db_name = 'aaa';
    protected $db_user = 'root';
    protected $db_pass = 'aaa';
    protected $db_host = 'localhost';
    

    public function connect() {
        $connection = new mysqli($this->db_host, $this->db_user, $this->db_pass, $this->db_name);
        //mysql_select_db($this->db_name);
        
        return true;
    }
    
    public function insert($data, $table) {    
        $columns = "";
        $values = "";
        foreach ($data as $column => $value) {
            $columns .= ($columns == "") ? "" : ", ";
            $columns .= $column;
            $values .= ($values == "") ? "" : ", ";
            $values .= $value;
        }
        $sql = "insert into $table ($columns) values ($values)";        
        mysql_query($sql) or die(mysql_error());
        return mysql_insert_id();
        echo 'Dziękujemy, że dodałeś artykuł:)';
    }
    
}

?>


dzieki.php

Kod
<?php
include 'class/DB_pt.class.php';
$db = new DB();
$db -> connect();
$data = array(
"$_POST[autor]" => "autor",
"$_POST[tytul]" => "tytul",
"$_POST[tekst]" => "tekst"
);
$db->insert($data, 'artykuly');
?>




Na pewno ścieżki i nazwy tabel są prawidłowe, czy ktoś może mi wskazać błąd?
mortus
W jednej linii korzystasz z mysqli, a w kolejnej z mysql.

PS. Funkcja insert korzysta z funkcji mysql_*, a nie z mysqli_*. Wybierz albo jedno, albo drugie.
404
Używasz 2 rzeczy, których raczej nie wypada mieszać. Tworzysz obiekt MySQLi, a następnie wywołujesz funkcje MySQL.

@up: uprzedził mnie kolega smile.gif
marcwars
Cytat(mortus @ 26.01.2013, 12:09:32 ) *
W jednej linii korzystasz z mysqli, a w kolejnej z mysql.

PS. Funkcja insert korzysta z funkcji mysql_*, a nie z mysqli_*. Wybierz albo jedno, albo drugie.


Niestety, wstawiłem w kodzie klasy:

zamiast:
Kod
mysql_query($sql) or die(mysql_error());
        return mysql_insert_id();


nowy kod:

Kod
mysqli_query($sql) or die(mysql_error());
        return mysqli_insert_id();


ale wychodzi błąd mysqli_query() expects at least 2 parameters, 1 given in 'nazwa_pliku' on line 76, to zła funkcja w mysqli?
aras785
Daj wszystko. No i funkcji insert (w/w) najpierw komunikat, a później return smile.gif
marcwars
Zmieniłem kolejność, ale dalej pojawia się ten sam błąd, czyli, że funkcja mysqli_query potrzebuje co najmniej 2 parametrów, a jest tylko 1:)
abort
mysqli_query działa w dwóch trybach: proceduralnym i obiektowym. W trybie obiektowym wystarczy jeden parametr, w trybie proceduralnym funkcja OCZEKUJE dwóch parametrów. Ty używasz mysqli w trybie proceduralnym (pomimo tego że uzywasz tego w innym obiekcie). Więcej w manualu: http://pl1.php.net/manual/en/mysqli.query.php (take z przykładami użycia obu trybów). Przeczytaj, przetraw - przecież nie będziemy Ci tłumaczyć sposobu używania funkcji, bo od tego jest manual...

marcwars
Zmieniłem w klasie funkcję insert na:

Kod
public function insert($data, $table) {    
        $columns = "";
        $values = "";
        foreach ($data as $column => $value) {
            $columns .= ($columns == "") ? "" : ", ";
            $columns .= $column;
            $values .= ($values == "") ? "" : ", ";
            $values .= $value;
        }
$con = $this->connect();
        $sql = "insert into $table ($columns) values ($values)";        
        $result = $con->query($sql);
echo 'Dziękujemy, że dodałeś artykuł:)<br />';
        return $result;
        
    }


Nie pokazuje błędu, ale nie dodaje danych do bazy, czy wiecie gdzie jest błąd?
mortus
Przecież według tego, co pisałeś na początku, metoda connect zwraca true. Zatem nowa wersja metody insert jest kompletnie bez sensu. Tutaj nie chodziło o nieprawidłową budowę funkcji insert, ale o to, że naprzemiennie wykorzystujesz mysql i mysqli, a powinieneś korzystać tylko z jednego z tych dwóch rozszerzeń. Przede wszystkim zachęcam do przejrzenia tego fragmentu dokumentacji, bo wszystko jest tam dokładnie pokazane w przykładach.

PS: Na pierwszy rzut oka pętla foreach nie zbuduje Ci prawidłowego fragmentu zapytania.
abort
Nie wiemy. Fusów nie mamy, bo herbatę pijemy ekspresową, kawę zrestą tez z ekspresu. A szklana kula nam się zepsuła.

Od tego jest debugowanie, w którym pomagają takie zaklęcia jak echo, print_r czy var_dump. Ponadto przy pracy z bazą danych warto przetestować komendę SQL w konsoli bazy.
marcwars
Poprawiłem kod pliku z klasą, tak że funkcja connect() już nie zwraca true, ale połączenie z bazą:

Kod
<?php

class DB {
    
    protected $db_name = 'aaa';
    protected $db_user = 'root';
    protected $db_pass = 'aaa';
    protected $db_host = 'localhost';
    

    public function connect() {
        $connection = new mysqli($this->db_host, $this->db_user, $this->db_pass, $this->db_name);
            
        return $connection;
    }
    
   public function insert($data, $table) {    
        $columns = "";
        $values = "";
        foreach ($data as $column => $value) {
            $columns .= ($columns == "") ? "" : ", ";
            $columns .= $column;
            $values .= ($values == "") ? "" : ", ";
            $values .= $value;
        }
$con = connect();
        $sql = "insert into $table ($columns) values ($values)";        
        $result = $con->query($sql);
echo 'Dziękujemy, że dodałeś artykuł:)<br />';
        return $result;
        
    }
    
}

?>


Niestety teraz pokazuje mi, że odwołuje się do nieznanej funkcji connect(), chociaż ta wcześniej jest public...
mortus
Wywołując connect() nie odnosisz się do metody zdefiniowanej wewnątrz klasy, ale do jakiejś tam globalnej funkcji (która w tym przypadku nie istnieje).
Użyj $this->connect().

Poza tym kilka uwag:
  • dane dostępu do bazy nie powinny być przechowywane na sztywno w klasie - pamiętaj, że one mogą się zmieniać, zatem powinny być zlokalizowane np. w pliku konfiguracyjnym i przekazywane/pobierane w momencie tworzenia instancji klasy DB
  • połączenie z bazą danych powinieneś nawiązać raz, a co za tym idzie powinno to nastąpić w momencie tworzenia instancji klasy DB
  • pamiętaj, że metody mogą zwracać różne wartości i warto to kontrolować, bo w tej chwili nie wiemy (nie wiesz), czy w ogóle udaje Ci się nawiązać połączenie z bazą danych
marcwars
Witam, wstawiłem $con=$this->connect(), ale nie działa- kod nie dodaje danych do bazy, nie pokazuje też żadnego błędu i pojawiają się końcowe o dodaniu do bazy.

Kod
public function insert($data, $table) {    
        $columns = "";
        $values = "";
        foreach ($data as $column => $value) {
            $columns .= ($columns == "") ? "" : ", ";
            $columns .= $column;
            $values .= ($values == "") ? "" : ", ";
            $values .= $value;
        }
$con = $this->connect();
        $sql = "INSERT INTO $table ($columns) VALUES ($values)";        
        $result = $con->query($sql);
echo 'Dziękujemy, że dodałeś artykuł:)<br />';
        return $result;
        
    }


mortus
Zapewne dlatego, że źle definiujesz tablicę $data (tzn. zamieniasz wartości z nazwami kolumn podczas odbierania danych z $_POST). Poczytaj o sposobach na debugowanie skryptu php.
marcwars
Wszystko prawie działa, ale przy jednej zmiennej, czyli kod dodaje autora do bazy:

Kod
error_reporting(E_ALL);
ini_set('display_errors', '1');
include 'class/DB_pt.class.php';
$db = new DB();
$db -> connect();
$autor = 'autor';
define('autor', 'autor');


$data = array(
$autor => $_POST[autor],
//$tytul => $_POST[tytul],
//$tekst => $_POST[tekst]
);
$db->insert($data, 'artykuly');


ale już kod poniżej nic nie dodaje:

Kod
error_reporting(E_ALL);
ini_set('display_errors', '1');
include 'class/DB_pt.class.php';
$db = new DB();
$db -> connect();
$autor = 'autor';
define('autor', 'autor');
$tytul = 'tytul';
define('tytul', 'tytul');
$tekst = 'tekst';
define('tekst', 'tekst');

$data = array(
$autor => $_POST[autor],
$tytul => $_POST[tytul],
$tekst => $_POST[tekst]
);
$db->insert($data, 'artykuly');


Jaka jest tego przyczyna? Zmienne są podobnie opisane.
mortus
  1. // zamiast
  2. $data = array(
  3. $autor => $_POST[autor],
  4. // ...
  5. );
  6. // powinno być
  7. $data = array(
  8. 'autor' => $_POST['autor'],
  9. 'tytul' => $_POST['tytul'],
  10. 'tekst' => $_POST['tekst']
  11. );


Oczywiście te dane trzeba jeszcze przefiltrować, bo w tej chwili skrypt narażony będzie na SQL Injection.
Nie obraź się, ale zabierasz się za programowanie obiektowe, a podstawy "leżą". Sięgnij po jakąś lekturę, czy tutorial.

Klasę, którą napisałeś mógłbyś zastąpić PDO.
marcwars
@Mortus, to prawda, że podstawy trochę u mnie leżą, stąd staram się przypomnieć je na realnym przykładzie.

Wstawiłem tak:
Kod
error_reporting(E_ALL);
ini_set('display_errors', '1');
include 'class/DB_pt.class.php';
$db = new DB();
$db -> connect();
$autor = 'autor';
define('autor', 'autor');
$tytul = 'tytul';
define('tytul', 'tytul');
$tekst = 'tekst';
define('tekst', 'tekst');

$data = array(
'autor' => $_POST[autor],
'tytul' => $_POST[tytul],
'tekst' => $_POST[tekst]
);
$db->insert($data, 'artykuly');

... ale ten kod nie dodaje nic do bazy, komunikat pojawia się zgodny z funkcją insert($data, $table) z klasy.
Jak dodam do powyższego kod:
Kod
print_r($data);
to mi się wyświetla prawidłowo tablica, czyli:
Cytat
Array ([autor] => xxx [tytul] => xxx [tekst] => xxx )
Już sam nie wiem, co może być nie tak.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.