Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zmiana wartosci rekordu
Forum PHP.pl > Forum > Bazy danych > MySQL
Wolfie
Witam

Napisalem taki skrypcik treningowy, szczerze to praktycznie przepisalem go z ksiazki, niestety w kodzie jak sie okazuje jest sporo bledow a errata online wydaje sie niekompletna. Poproawilem z 3 bledy ale z tym nie potrafie sobie poradzic.
Chodzi o zmiane wartosci w tabeli mysql przez wywolanie odpowiedniej metody w klasie.
Oto kod.

  1. <?php
  2. //class.Widget.php
  3.  
  4. class Widget {
  5.  
  6.    private $id;
  7.    Private $name;
  8.    private $description; private $hDB;
  9.    private $needsUpdating = false;
  10.    
  11.    public function __construct($widgetID) {
  12.        //parametr widgetID to klucz główny rekordu
  13.        //w bazie danych zawierajacego dane
  14.        //tego obiektu
  15.        
  16.        //tworzy uchwyt połaczenia i zachowuje go w prywatnej zmiennej skladowej
  17.        $this->hDB = mysql_connect('localhost', 'root', "");
  18.        if(!is_resource($this->hDB)) {
  19.            throw new Exception ('Nie mozna polaczyc sie z baza danych.');
  20.            }
  21.            
  22.        $db = mysql_select_db ('webserv',$this->hDB);
  23.        
  24.        $sql = "SELECT nazwa, opis FROM artykul WHERE nr_artykulu = '$widgetID' ";
  25.        $rs = mysql_query($sql, $this->hDB);
  26.        if(!is_resource($rs)) {
  27.            throw new Exception ("Blad przy wykonywaniu instrukcji wyboru.");
  28.            }
  29.            
  30.        if(!mysql_num_rows($rs)) {
  31.            throw new Exception('Szukanego artykulu nie ma w bazie!');
  32.            }
  33.            
  34.        $data = mysql_fetch_array($rs);
  35.        $this->id = $widgetID;
  36.        $this->name = $data['nazwa'];
  37.        $this->description = $data['opis'];
  38.    
  39.    }
  40.    
  41.    public function getName() {
  42.        return $this->name;
  43.        }
  44.        
  45.    public function getDescription() {
  46.        return $this->description;
  47.        }
  48.        
  49.    public function setName($name) {
  50.        $this->name = $name;
  51.        $this->needsUpdating = true;
  52.        }
  53.    
  54.    public function setDescription($description) {
  55.        $this->description = $description;
  56.        $this->needsUpdating = true;
  57.        }
  58.    
  59.    public function __desctruct() {
  60.        if(!$this->needsUpdating) {
  61.            return;
  62.            }
  63.        
  64.        $sql = 'UPDATE artykul SET';
  65.        $sql .= "nazwa = '" .mysql_escape_string($this->name). "'.";
  66.        $sql .= "opis = '" .mysql_escape_string($this->description). "'.";
  67.        $sql .= "WHERE nr_artykulu = " .$this->id;
  68.        
  69.        $rs = mysql_query($sql, $this->hDB);
  70.        if(!is_resource($rs)) {
  71.            throw new Exception ('Wystapil blad podczas aktualizacji bazy danych');
  72.        }
  73.        
  74.    //koniec operacji na bazie danych. Zamkniecie połączenia.
  75.    mysql_close($this->hDB);
  76.    
  77.    }    
  78.  
  79. }
  80. ?>


A tutaj miejsce inicjalizacji obiketu oraz wywolanie metod :

  1. <?php
  2.  
  3. require_once('class.Widget.php');
  4.  
  5. try {
  6.    $objWidget = new Widget(1);
  7.    
  8.    print "Nazwa artykułu: " . $objWidget->getName(). "<br>\n";
  9.    print "Opis artykulu: " . $objWidget->getDescription(). "<br>\n";
  10.    
  11.    $objWidget->setName('Trampki');
  12.    $objWidget->setDescription('Trampki o duzym przebiegu!');
  13. } catch (Exception $e) {
  14.    die ("Wystapil problem: " . $e->getMessage());
  15.    }
  16. ?>


Jak zapewnia autor po kolejnym wywolaniu strony automatycznie powinny zmienic sie wartosci w bazie danych poprzez uzycie metod setName oraz setDescription. Jednak kolejne wywolania nic nie daja, dopiero po wyswietleniu wartosci po instrukcji try...catch widac wyswietla sie zmieniona wartosc , lecz w bazie danych pozostaje bez zmian.
Foxx
Musisz dodać jeszcze jedną linijkę niszczącą obiekt (wywołać destruktor, czyli metodę __destruct()):
  1. <?php
  2. $objWidget->setDescription('Trampki o duzym przebiegu!');
  3. unset($objWidget); // to wywoła destruktor a on updatuje Twój obiekt
  4. ?>
Wolfie
Niestety nic to nie pomoglo , ciagle to samo.....
Foxx
Zmień metodę __destruct klasy Widget tak:
  1. <?php
  2. public function __desctruct() {
  3.       if(!$this->needsUpdating) {
  4.          echo 'needs no updating';
  5.          return;
  6.       }
  7.       echo 'needs updating';
  8.       $sql = 'UPDATE artykul SET';
  9.       $sql .= "nazwa = '" .mysql_escape_string($this->name). "'.";
  10.       $sql .= "opis = '" .mysql_escape_string($this->description). "'.";
  11.       $sql .= "WHERE nr_artykulu = " .$this->id;
  12.  
  13.       echo $sql;
  14.  
  15.       $rs = mysql_query($sql, $this->hDB) or die(mysql_error());
  16.       if(!is_resource($rs)) {
  17.           throw new Exception ('Wystapil blad podczas aktualizacji bazy danych');
  18.       }
  19.      
  20.   //koniec operacji na bazie danych. Zamkniecie połączenia.
  21.   mysql_close($this->hDB);
  22.  
  23.   }
  24. ?>


A plik, w którym jej używasz na taki:
  1. <?php
  2. require_once('class.Widget.php');
  3.  
  4. try {
  5.   $objWidget = new Widget(1);
  6.  
  7.   print "Nazwa artykułu: " . $objWidget->getName(). "<br>\n";
  8.   print "Opis artykulu: " . $objWidget->getDescription(). "<br>\n";
  9.  
  10.   $objWidget->setName('Trampki');
  11.   $objWidget->setDescription('Trampki o duzym przebiegu!');
  12.  
  13.   print "Nowa nazwa artykułu: " . $objWidget->getName(). "<br>\n";
  14.   print "Nowy opis artykulu: " . $objWidget->getDescription(). "<br>\n";
  15.  
  16.   $unset($objWidget);
  17. } catch (Exception $e) {
  18.   die ("Wystapil problem: " . $e->getMessage());
  19. }
  20. ?>

I powiedz co wyświetla.
Wolfie

Cytat
Nazwa artykułu: Korale
Opis artykulu: Korale koloru koralowego
Nowa nazwa artykułu: Trampki
Nowy opis artykulu: Trampki o duzym przebiegu!

Fatal error: Function name must be a string in C:\Program Files\WebServ\httpd\OOP\PHP5\testWidget.php on line 16


Linia 16-sta to ta :
  1. <?php
  2. unset($objWidget);
  3. ?>
erix
Funkcji zamykania połączenia/etc nie powinno się umieszczać w destruktorze. winksmiley.jpg
Mephistofeles
A zwróciłeś uwagę na " __desctruct()"? Poza tym wcale nie trzeba usuwać obiektu, PHP robi to automatycznie (w normalnych warunkach oczywiście).
Erix, czemu się nie powinno?
erix
Ponieważ prowadzi to nieraz do nieprzewidywalnych sytuacji, typu resource of unknown, czy innych błędów.

Niestety, jeśli chodzi o destruktory, to developerzy PHP się nie popisali...
Mephistofeles
No OK, ale jak chcę automatycznie zapisać dane do bazy po zniszczeniu obiektu, ale nie zamykam połączenia, to mogę zostawić to w destruktorze?
Wolfie
Chyba zaczyna sie robic OT. Ja chce tylko znac poprawne rozwiazanie zeby moc dalej przerabiac material ksiazki winksmiley.jpg
Wiec chodzi o pojedyncze wywolanie parametrow a po przeladowaniu zmiane wartosci w tabelach.
Niestety zadna z powyzszych metod tego nie zapewnia.

Wartosci w tabeli ciagle pozostaja bez zmian , co prawda nastepuje zmiana nazwy na poziomie klienta ale nie nastepuje zadna zmiana w tabelach.
Mephistofeles
Zapytałem, czy zwróciłeś uwagę na błąd w nazwie destruktora?
Wolfie
Wlasnie nie wiedzialem do kogo to pytanie winksmiley.jpg
Teraz juz lepiej , za to pojawil sie blad aktualizacji bazy danych.

Czy ta czesc kodu jest poprawna ?
Głównie chodzi o ta dluga zmienna $sql ktora przechowuje zapytanie.

  1. <?php
  2. public function __destruct() {
  3.        if(!$this->needsUpdating) {
  4.            echo 'needs no updating';
  5.            return;
  6.            }
  7.        
  8.        $sql = 'UPDATE artykul SET';
  9.        $sql .= "nazwa = '" .mysql_escape_string($this->name). "'.";
  10.        $sql .= "opis = '" .mysql_escape_string($this->description). "'.";
  11.        $sql .= "WHERE nr_artykulu = " .$this->id;
  12.        
  13.        $rs = mysql_query($sql, $this->hDB);
  14.        if(!is_resource($rs)) {
  15.            throw new Exception ('Wystapil blad podczas aktualizacji bazy danych');
  16.        }
  17. ?>


Wywala sie ostatni exception z pliku class.Widget.php
artur_dziocha
no to przejrzyj/wyświetl sobie zapytanie
chyba coś ze spacjami jest nie tete i nie wiem czy przecinki:)
Mephistofeles
To nie przecinki a kropki. Popraw. No i brakuje spacji.
PS. Jak używasz już apostrofów, to zostaw tak do końca, jest to lepsza technika winksmiley.jpg.
Wolfie
Wprowadzilem nieznaczne zmiany w zapytaniu , teraz wyswietla sie znakomicie , jednak problem ciagle istnieje , wyskakuje exception zwiazany z aktualizacja.

Pokaze jeszcze poprawny kod zapytania $sql:

  1. <?php
  2. $sql = 'UPDATE artykul SET ';
  3.        $sql .= "nazwa = '" .mysql_escape_string($this->name). "' ";
  4.        $sql .= "opis = '" .mysql_escape_string($this->description). "' ";
  5.        $sql .= "WHERE nr_artykulu = " .$this->id;
  6. ?>
Foxx
Wprowadź taką zmianę (o której już pisałem raz)
  1. <?php
  2. $rs = mysql_query($sql, $this->hDB) or die(mysql_error());
  3. ?>

i zobaczysz komunikat.

Edit: popraw też ostatnią część zapytania sql:
  1. <?php
  2. $sql .= "WHERE nr_artykulu='".$this->id."'"; // tak jest poprawnie
  3. ?>
Mephistofeles
Skoro trzymasz się wyjątków to lepiej - throw new Exception (mysql_error());

Edit: Wciąż nie jest poprawnie, brakuje ci przecinka tu: $this->name). "' ";, wstaw takie coś:
  1. <?php
  2. $sql = 'UPDATE artykul SET ';
  3. $sql .= "nazwa = '" .mysql_escape_string($this->name). "', ";
  4. $sql .= "opis = '" .mysql_escape_string($this->description). "' ";
  5. $sql .= "WHERE nr_artykulu = " .$this->id;
  6. ?>
Wolfie
Wyswietla sie taki komunikat :

Cytat
Something is wrong in your syntax obok 'opis = 'Trampki o duzym przebiegu!' WHERE nr_artykulu='1'' w linii 1


Ale wyswietlone zapytanie wydaje sie byc poprawne :
Cytat
UPDATE artykul SET nazwa = 'Trampki' opis = 'Trampki o duzym przebiegu!' WHERE nr_artykulu='1'



OK!
Znalazlem blad , brak przecinka w zapytaniu po pierwszym parametrze komendy SELECT
Mephistofeles
Spójrz wyżej! Brakuje ci przecinka.
Wolfie
Tez to zauwazylem po dokladnym przyjrzeniu sie dlatego edytowalem poprzedni post , teraz wszystko dziala , dzieki , moge uczyc sie dalej exclamation.gif laugh.gif
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.