Wątek przeniesiony 2014-12-29 19:31 z przez dzek69. Powód: Wątek dotyczący podstaw

Zamiast nazwiska z polskimi znakami pobiera null

Odpowiedz Nowy wątek
2014-12-29 18:43
0

Witam.
Ćwiczę sobie pobieranie danych za pomocą jQuery, ćwiczę robiąc klasyczną "Bibliotekę". Wszystko szło jak pomaśle, kiedy napotkałem na pewien dziwny błąd. Mianowicie mam problem związany z pobieraniem danych z bazy danych. Pobieram listę książek, i tam gdzie pojawi mi się jaki kolwiek String który zawiera polski znak, pobierany jest z bazy jako NULL mimo że w niej (podgląd za pomocą phpMyAdmin) wszystko jest normalnie, dla bazy ustawiłem porównywanie napisów na utf8_polish_ci.

Po drugie, wynik zapytania na stronie jest zupełnie inny niż na bazie danych.
Powtarzają się dane, drugie się nie wyświetlają, następne mają null, lub mają skrócone nazwy.

Nie rozumiem czemu tak się dzieje, proszę o pomoc.

Screen z bazy:

baza.jpg

Adres do aplikacji: www.storin.rdl.pl/jquery

Oto kod PHP z zapytaniami:

<?php
    include_once "connection.php";
 
global $akcja;
$akcja = $_POST['akcja'];     
$akcjaGET = $_GET['akcja']; 
 
// DODAWANIE
if($akcja == 'dodajKsiazke'){
    $nazwa = $_POST['nazwa'];
    $isbn =  $_POST['isbn'];
    $autor =  $_POST['autor'];
    $polka = $_POST['polka'];
 
    $query = mysql_query("INSERT INTO `ksiazki`(`nazwa`, `isbn`, `autor_id`, `polka`) VALUES ('$nazwa', '$isbn', $autor, $polka)");
 
// Zwracanie ID ostatnio utworzonego INSERT'A    
    $lastId = array();
    $lastId['lastId'] = mysql_insert_id(); 
    //echo $lastId; 
    echo json_encode($lastId);    
 
// LISTA KSIĄŻEK    
} else if($akcja == 'pokazKsiazki' || $akcjaGET == 'pokazKsiazki'){
    $query = mysql_query("SELECT ksiazki.id, ksiazki.nazwa, ksiazki.isbn, autor.imie, autor.nazwisko, ksiazki.polka  FROM ksiazki, autor WHERE ksiazki.autor_id = autor.id "); 
 
    if(mysql_num_rows($query) > 0){
        while($row = mysql_fetch_object($query)){
            $ksiazki[] = $row; 
        }
    }
 
    echo json_encode($ksiazki);   
    //echo "1"; 
} else if($akcja == 'edytujKsiazke'){
    //echo "1";
 
    $set = ""; 
    $idEdit = $_POST['idEdit']; 
 
    if(isset($_POST['nazwaEdit'])){
        $nazwa = $_POST['nazwaEdit']; 
        $set .= "nazwa='".$nazwa."', "; 
    }
    if(isset($_POST['isbnEdit'])){
        $isbn =  $_POST['isbnEdit'];
        $set .= "isbn='".$isbn."', ";
    }
    if(isset($_POST['autorEditId'])){
        $autor =  $_POST['autorEditId'];
        $set .= "autor_id=".$autor.", ";
    }
    if(isset($_POST['polkaEdit'])){
        $polka = $_POST['polkaEdit'];
        $set .= " polka=".$polka;
    }
    //echo $idEdit; 
    //echo $set;
    //echo $idEdit; 
 
    mysql_query("UPDATE ksiazki SET $set WHERE id = $idEdit");
    echo "1";
} else if($akcja == "usunKsiazke"){
 
    $idUsun = $_POST['idUsun'];
 
    mysql_query("DELETE FROM ksiazki WHERE id = $idUsun"); 
    echo "1"; 
 
} else if($akcja == 'pokazAutor'){
     $query = mysql_query("SELECT * FROM autor"); 
 
    if(mysql_num_rows($query) > 0){
        while($row = mysql_fetch_object($query)){
            $autor[] = $row; 
        }
    }
    echo json_encode($autor);   
 
}
 
?>
  • baza.jpg (0,14 MB) - ściągnięć: 65
edytowany 6x, ostatnio: furious programming, 2014-12-29 21:53

Pozostało 580 znaków

2014-12-29 18:53
1

Zmień kodowanie na uft8 unicode, używaj biblioteki PDO, filtruj jakoś dane bo teraz Ci każdy moze zdropować baze bez większego problemu. Wyrazy są skracane najczęściej od momentu napotkania niewłaściwego znaku, tj. polskiego.

edytowany 1x, ostatnio: miej95, 2014-12-29 18:54

Pozostało 580 znaków

2014-12-29 19:00
0

Zmiana kodowania niestety nie pomogła. Robiłem identycznie to samo wcześniej używając biblioteki mysql i nie było żadnych problemów.
Czy zmiana na PDO ma faktycznie jakieś znaczenie w tym problemie czy to tylko rada ?

edytowany 1x, ostatnio: furious programming, 2014-12-29 21:54

Pozostało 580 znaków

2014-12-29 19:31
1

To jest rada, bo w tym momencie kod masz dziurawy jak sito.

polecenie SET NAMES (googluj co dalej :>) na 99% naprawi problem


Pozostało 580 znaków

2014-12-30 10:28
0
 
<?php
 
$connection = mysql_connect('*****', '*****', '*****'); 
if($connection){
    echo " Połączenie udane"; 
}
mysql_select_db("*******"); 
mysql_query("SET NAME 'utf8'"); 
 
if(!$connection){
    die('Błąd połączenia z bazą danych: ' . mysql_error()); 
}
 
//echo 'Połączenie prawidłowe'; 
 
?>

Miałem to od początku.
Czyli rozumiem połączenie do bazy i wysyłanie zapytań jest bezpieczniejsze ? PDO nie przyjmuje zapytań w wysyłanych danych INSERT INTO ?

edytowany 3x, ostatnio: dzek69, 2014-12-30 12:45

Pozostało 580 znaków

2014-12-30 10:36
1

SET NAME, a SET NAMES to jest chyba różnica, nieprawdaż?

Co do PDO - tam nie budujesz (można, ale nie powinieneś) zapytań sam, tylko masz coś takiego:

$sth = $dbh->prepare('INSERT INTO `ksiazki`(`nazwa`, `isbn`, `autor_id`, `polka`) VALUES (:nazwa, :isbn, :autor_id, :polka)');
$sth->bindParam(':nazwa', $_POST['nazwa'], PDO::PARAM_STR, 50);
$sth->bindParam(':isbn', $_POST['isbn'], PDO::PARAM_STR, 20);
$sth->bindParam(':autor_id', $_POST['autor'], PDO::PARAM_INT);
$sth->bindParam(':polka', $_POST['polka'], PDO::PARAM_INT);
$sth->execute();

Nie podając żadnych zmiennych wewnątrz zapytania bezpośrednio, tylko poprzez bindParam (lub bindValue - poczytaj w manualu jaka jest różnica) zabezpieczasz się przed SQLInjection. Zauważ, że w bindParam definiujesz dodatkowo (wedle potrzeby, domyślnie jest to string) spodziewany typ zmiennej, oraz ew. maksymalną długość (jak w bazie).

Kolejna rzecz: Mówiłeś, że w phpMyAdmin masz dobrze, a ID 30 jest źle ;)


edytowany 1x, ostatnio: dzek69, 2014-12-30 10:44

Pozostało 580 znaków

2014-12-30 11:43
0

Dziękuje bardzo za pomoc, za chwile przerobie sobie wszystko na PDO.

Co do problemy z wyświetlaniem nulla, SET NAMES załatwiło sprawę, pozostał jednak jeszcze problem błednie wyświetlanych danych, response json'a jest ok, jednak pliki są źle wyświetlane w tabeli co dla mnie też jest nie wytłumaczalne.

Screen tego problemu:

response.jpg

edytowany 1x, ostatnio: storin, 2014-12-30 11:44

Pozostało 580 znaków

2014-12-30 12:05
1

Ale co Ci się źle wyświetla? Pan Wołodyjowski? Przecież to już w bazie masz źle! (na co zwróciłem Ci uwagę w poprzednim poście)


Pozostało 580 znaków

2014-12-30 12:41
0

Zobacz jakie rekordy mam w bazie danych, a jakie mi się wyświetlają w aplikacji. Pan Wołodyjowski źlę się wyświetla ponieważ umieszczałem go w bazie poprzez aplikacje, i bez kodowania się tak zapisał, ale na niego w ogóle nie zwracam uwagi, chodzi mi o niezgodność rekodrdów, a nawet powtarzanie się kilku (3 ostatnie).

edytowany 1x, ostatnio: dzek69, 2014-12-30 12:45

Pozostało 580 znaków

2014-12-30 12:44
1

Poczytaj o (LEFT) JOIN - i pierwsze zapytania popróbuj sobie wykonywać w phpMyAdmin, zanim przerobisz je na kod - tak żebyś widział jak Twoje eksperymenty wpływają na wyniki


Pozostało 580 znaków

2014-12-30 12:49
0

Zapytanie jest dobre, wyświetliłem specjalnie obok response jaki otrzymałem z pliku PHP z zapytaniami, przetestowałem te zapytanie bezpośrednio w phpMyAdmin, jak i w shellu i wszędzie jest dobrze, problem jest z wyświetlaniem tych danych w przeglądarce, z jakiegoś powodu wyświetla źle. Załącze do tego kod JS.

 
function loadBookList(){
 
    $.ajax({
        type: "POST",
        url: "querys.php", 
        dataType: 'json', 
        data: {
            akcja : 'pokazKsiazki'
        },
        success : function(json){
            console.log(json);
            for(var klucz in json ){
                console.log(json[klucz[0]].id);
 
                var idGET = json[klucz[0]].id; 
                var nazwaGET = json[klucz[0]].nazwa; 
                var isbnGET = json[klucz[0]].isbn; 
                var imieGET = json[klucz[0]].imie; 
                var nazwiskoGET = json[klucz[0]].nazwisko; 
                var polkaGET = json[klucz[0]].polka; 
 
                $("#tabela").append('<tr><td>'+idGET+'</td><td>'+nazwaGET+'</td><td>'+isbnGET+'</td><td>'+imieGET+' '+nazwiskoGET+'</td><td>'+polkaGET+'</td><td><a href="#" class="edit"><img src="img/edit.png" alt="Edytuj"/></a><a href="#" class="delete"><img src="img/delete.png" alt="Usuń"/></a></td></tr>');
                registerHandlers();
            }
        },
        error: function(blad){
 
          console.log(blad); 
        }
 
    }); 
}

Dodam że wcześniej bez SET NAMES, rekordy pobierane do pliku były odpowiednio, problem zaczynał się w momencie json_encode($ksiazki);, funkcja wysyłała rekordy z polskimi znakami jako null, lecz SET NAMES naprawiło problem.

edytowany 4x, ostatnio: dzek69, 2014-12-30 12:56
Nie cytuj poprzedniego posta w całości - nie ma to sensu. Cytuj, jeżeli potrzebujesz odnieść się do konkretnego fragmentu poprzedniej wypowiedzi, bądź odpowiedzi wcześniej niż ostatni post. I zawsze używaj tagów kolorujących składnię. - dzek69 2014-12-30 12:57

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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