Ajax - w jaki sposób odczytać informacje w przypadku niepowodzenia zapisu do bazy danych?

0

Mam taki przykład w którym niezależnie czy dobrze sformułowane jest zapytanie do bazy danych czy nie to zawsze wyświetla się komunikat że informacje zostały prawidłowo dodane do bazy.

Nie umiem przerobić tego aby poprawnie wywołać (error:). próbowałem w pliku wyślij wstawiać różne echo ale nie umiem przechwycić tego w Ajax.
Będę wdzięczny za wszelką pomoc.

//  plik: skrypt.js
$(document).ready(function(){
     
    $('#wyslij').click(function() { 
        var wartosc_z_listy = $('#lista').val();
        $.ajax({
            type:"POST", 
            url:"wyslij.php", 
            data: {klucz_ajax:wartosc_z_listy},
                success:function() {
                    alert("Wysłano do bazy danych"); 
                    console.log("Wysłano do bazy danych");
                },
                error: function(blad) {
                    alert( "Wystąpił błąd");
                    console.log(blad); 
                }
        });
    });
 
    $('#pobierz').click(function() { 
        $.ajax({
            type:"GET", 
            url:"pobierz.php", 
            contentType:"application/json; charset=utf-8", 
            dataType:'json', 
                success: function(json) {
                    $('#wykaz').html('');
                    for (var klucz in json)
                        {
                            var wiersz = json[klucz];     
                            var id = wiersz[0];
                            var nazwakraju = wiersz[1];
                            $("<span>id: "+id+" nazwa: "+nazwakraju+"</span>")
                            .appendTo('#wykaz')
                            .append("<hr>")
                        } 
                },
                error: function(blad) {
                    alert( "Wystąpił błąd");
                    console.log(blad); 
                }
        });
    });
}); 
 //  plik: wyslij.php
require_once('baza.php');

$wartosc_z_listy_post = $_POST['klucz_ajax'];

$zapytanie_wyslij = "INSERT INTO kraje (nazwa_krajux) VALUES ('$wartosc_z_listy_post')";

$wynik_wyslij = mysqli_query($db, $zapytanie_wyslij);

 //  plik: pobierz.php
header('Content-type: application/json');

require_once('baza.php');

$zapytanie_pobierz = "SELECT id, nazwa_kraju FROM kraje";

$wynik_pobierz = mysqli_query($db, $zapytanie_pobierz);

$pobrane_dane = array();

while ($wiersz = mysqli_fetch_row($wynik_pobierz)) {
    $pobrane_dane[] = $wiersz;
}
echo json_encode($pobrane_dane);

 //  plik:baza.php
$serwer = 'localhost';
$uzytkownik = 'adam';
$haslo = 'test';
$nazwa_bazy = 'ajax_php_con';
  
$db = mysqli_connect($serwer, $uzytkownik, $haslo, $nazwa_bazy);
 
if (mysqli_connect_errno()) 
{
    echo 'Błąd';
    exit;   
}
else {
}

 //  plik: index.html
<!doctype html>
<html>
<?php
require_once('baza.php');
?>
<head>
<meta charset="utf-8">
<title>Ajax</title>
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="skrypt.js"></script> 
</head>
<body>
<br/>
    <form>
        <select id="lista">
          <option value="Polska">Polska</option>
          <option value="Węgry">Węgry</option>
          <option value="Czechy">Czechy</option>
          <option value="Austria">Austria</option>
        </select> 
        <br/>
        <br/>
        <button id="wyslij" type="button">Wyślij</button> 
        <br/>
        <br/>
        <button id="pobierz" type="button">Pobierz wykaz</button> 
    </form>
     
    <br/>
    <br/>
    <!--Blok przeznaczony na przechowanie informacji pobieranych z bazy-->
    <div id="wykaz">
    </div>
 
</body>
</html>
1

Ale skąd ten AJAX ma wiedzieć o błędzie? Rzuć wyjątkiem może? Np.

if (mysqli_connect_errno()) {
    throw new RuntimeException("Connect failed: %s\n", mysqli_connect_error());
}
0

Nie bardzo wiem jak powinienem skonfigurować plik php czy wstawić jakiś nagówek jeśli tak to jaki jakie echo. Nie wiem też czy w funkcji error powinien być jakiś parametr czy też nie.

0

znalazlem taki przykład: http://kursjs.pl/kurs/jquery/jquery_ajax.php

$.ajax({
    type     : "POST",
    url      : "saveToDatabase.php",
    data     : {
        name : 'Marcin',
        country : 'Polska'
    },
    success: function(ret) {
        //ten fragment wykona się po pomyślnym zakończeniu połączenia - gdy dostaliśmy odpowiedź od serwera nie będącą błędem (404, 400, 500 itp)
        //atrybut ret zawiera dane zwrócone z serwera
    },
    complete: function() {
        //ten fragment wykona się po zakończeniu łączenia - nie ważne czy wystąpił błąd, czy sukces
    },
    error: function(jqXHR, errorText, errorThrown) {
        //ten fragment wykona się w przypadku BŁĘDU
        //do zmiennej errorText zostanie przekazany błąd
    }
});

Nie jest tu tylko napisane co powinien zawierać plik php aby przekazać wartości do prarametrów jqXHR, errorText, errorThrown
może jakiś nagłówek albo echo do tego przykładu?

Bardzo proszę o pomoc.

1

Jeśli dobrze pamiętam, error wykona się, gdy żądanie nie może zostać ukończone, czyli np. przy zwrotnym kodzie 500 z PHP.
Jeżeli więc próbujesz powiedzieć ajaxowi, że coś wykonało się źle, możesz zwrócić mu błąd 500, np. tak:

if(blad_zapytania czy tam nie wpisany rekord) { header("HTTP/1.1 500 Internal Server Error"); }

Problem w tym, że wtedy nie dowiesz się dokładnie co poszło nie tak.

Znacznie lepiej byłoby, jakbyś przechwycił każdy wyjątek w swoim kodzie PHP i wyrzucał jakiś mikro interfejs do ajaxa, gdzie będziesz miał dokładnie opisane w czym jest problem - użytkownik będzie dokładnie wiedział co poszło nie tak. Rozważ taki przykład:

$status=array('success'=>0,'msg'=>'Blad polaczenia z baza');
return json_encode($status);

po stronie JS:

// kod ajax
success: function(response) {
   response=$.parseJSON(response);
   if(!response['success']) { alert('Blad wykonania: '+response.msg); } // wyswietlasz co dokladnie poszlo nie tak
},

W tym przypadku, funkcja error, przechwyci Ci tylko wyjątek, np. gdy będziesz miał jakąś literówkę w PHPie (PHP wyrzuci błąd) albo nie otrzymasz odpowiedzi od skryptu wykonującego zapytanie (np,. niepoprawny url). Wtedy będziesz wiedział, że kod wykonany w funkcji error, to poważny błąd z serwerem, natomiast reszta (odpowiedzi via JSON) to błędy podczas wykonania konkretnych zapytań.

Oczywiście to pseudokod, trzeba dostosować go do swoich potrzeb. Looknij na stacku (https://stackoverflow.com/questions/18211954/handling-mysql-errors-when-using-ajax) fajnie jest to tam opisane.

0

Wykonałem coś takiego:

            success: function (json) {
                var komunikat = JSON.parse(json)
                if (komunikat != 'wsioOKI') {
                    alert('###   SuccesAlert  ### \n\n\n\ ' + komunikat);
                } else {
                    console.log('zapis do bazy wykonal sie poprawnie: - ' + komunikat);
                }
            },
$wynik_wyslij = mysqli_query($db, $zapytanie_wyslij);
if (mysqli_error($db)) {
    $ret= mysqli_error($db);
} else {
     $ret= 'wsioOKI';
}
echo json_encode($ret);

Czyli jesli wykonam błąd wewnątrz funcji error to nie będe wiedział jaki jest kod błędu?

1

Już dokładnie nie pamiętam, bo dawno nie korzystałem z AJAX, ale ogólnie funkcja error jak jest napisane w dokumentacji: "A function to be called if the request fails" - sprawdza czy żądanie AJAX ogólnie powiodło się, czy strona nie zwróci np. kodu 200. Innymi słowy czy PHP nie rzucił jakiś wyjątków, które wygenerowały kod odpowiedzi inny niż 200.

Natomiast jeżeli połączenie nastąpiło ok i nagłówek zwraca kod 200 (ALL OK) to nie przechwycisz błędów, które występują podczas wykonania kodu ale nie powodują błędu w samym pliku PHP (takich jak brak dodanego rekordu do bazy, błędna nazwa użytkownika, hasło czy cokolwiek). To musisz obrobić sobie wewnątrz kodu, np. takim skryptem jak napisałeś i wysłać te dane z powrotem oraz obrobić w funkcji success.

Innymi słowy - jeżeli sam plik i skrypt nie jest poprawny (błąd składni, szczególne wyjątki) i kod odpowiedzi jest inny niż 200 - przechwycisz to w funkcji error.
Jeżeli natomiast kod jest ok, ale jego wykonanie jest niezgodne z oczekiwaniami, musisz obrobić sobie to w skrypcie i wysłać taką informację z powrotem, którą przechwycisz w funkcji success.

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