Меню

Вывод ошибок php ajax

At the moment when I hover over any word a black box is always showing. If the PHP code returns text it is displayed in the black box (which it should). However I want it to return an error function if the text is not returned so I can then later change the CSS for the black box so that it has a width of 0px instead of 400px.

var x = ($(this).text());
$.ajax({
    type: 'POST',
    url: 'process.php',
    data: { text1: x },
    success: function(response){
        $('#tooltip').text(response);
    }
});
try 
{
    $db = new PDO('sqlite:ordbas.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
} catch(PDOException $err)
{
    echo "PDO fel $err";
}

if (isset($_POST['text1'])) {
    $text1 = $_POST['text1'];
    $results = $db->prepare("SELECT forord FROM words WHERE sokord='$text1'");
    $results->execute();
    $row = $results->fetch();
    echo $row[0];
}       

As you might have figured out there is some non-important code that I left out. I hope someone can understand and help me! Thanks!

Rory McCrossan's user avatar

asked May 17, 2016 at 11:57

Aplex's user avatar

2

Here is exactly how you can do it :

The Very Easy Way :

IN YOUR PHP FILE :

if ($query) {
    echo "success"; //anything on success
} else {
    die(header("HTTP/1.0 404 Not Found")); //Throw an error on failure
}

AT YOUR jQuery AJAX SIDE :

var x = $(this).text();
$.ajax({
    type: 'POST',
    url: 'process.php',
    data: { text1: x },
    success:function(data) {
        alert(data); //=== Show Success Message==
    },
    error:function(data){
        alert("error occured"); //===Show Error Message====
    }
});

answered May 17, 2016 at 12:31

Umair Shah Yousafzai's user avatar

4

First, you need to let know javascript there was an error on server side

try 
{
    $db = new PDO('sqlite:ordbas.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
} catch(PDOException $err)
{
    // Set http header error
    header('HTTP/1.0 500 Internal Server Error');
    // Return error message
    die(json_encode(array('error' => 'PDO fel '.$err->getMessage())));
}

Second, you need to handle error while loading json

var x = ($(this).text());
$.ajax({
   type: 'POST',
   url: 'process.php',
   data: { text1: x }
})

// This will be called on success 
.done(function(response){
   $('#tooltip').text(response);
})

// This will be called on error
.fail(function(response){
  // Error catched, do stuff
  alert(response);
});

answered May 17, 2016 at 12:39

Buksy's user avatar

BuksyBuksy

11.2k8 gold badges62 silver badges68 bronze badges

The fail callback within $.ajax is used for capturing any failing results.

show/hide the error div based on success/failure returned from server script.

HTML CODE:

     <div class="error"><div>

CSS:

 .error {
      color: red;
 }

JS CODE:

//hide error before ajax call
$('.error').hide(); 
$.ajax(...)
  .done:function(){
       ...
  }
  .fail: function(jqXHR, textStatus, errorThrown){
     $('.error').text(errorThrown); 
     $('.error').show();
  }

Note: .success() & .error() methods are deprecated from jquery 1.8 so avoid using them.

Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

answered May 17, 2016 at 12:12

dreamweiver's user avatar

dreamweiverdreamweiver

5,9842 gold badges27 silver badges39 bronze badges

In your catch you could put

header('Content-type: application/json');
echo json_encode(array('Error' => 'PDO fel "$err"'));

answered May 17, 2016 at 12:05

Rob B's user avatar

Rob BRob B

312 silver badges5 bronze badges

1

$.ajax({
    url: "file_name.php",
    method: "POST",
    data: $("#form_id").serialize(),
    success: function () {
        alert("success"); //do something
    },
    error: function () {
        alert("doh!"); // do something else
    }
});

This is an example for POST requests dealing with sensitive form data (or data that you’ll bind to a UPDATE or INSERT query, for example). I included the serialize() function in order to handle the name fields from the form on your back end. I also removed passing the data through the success function. You don’t want to do that when dealing with sensitive data or data you don’t plan on displaying. Figured I would post this here since this thread came up when I searched how to do a POST with AJAX that returns an error.

Speaking of returning an error, you’ll want to do this instead now that PHP has updated again. I also recommend reading through 5.4+ docs.

http_response_code(404);
die();

I threw in a die() function to make sure nothing else happens after you request your 404.

answered Mar 6, 2017 at 21:45

Christopher Northcutt's user avatar

0

Try with the following snippet instead:

var x = ($(this).text());
$.ajax({
    type: 'POST',
    url: 'process.php',
    data: { text1: x },
    success: function(response){
        $('#tooltip').text(response);
    },
    error: function(error) {
        console.log(error);
    }
});

answered May 17, 2016 at 12:06

Azenis's user avatar

1

Use the PHP function json_encode on an array. The array will then be presented to javascript as a JSON object (the ‘response’ argument/parameter).

In other words:

PHP:

// important to tell your browser what we will be sending
header('Content-type: application/json; charset=utf-8');

... bla bla code ...

// Check if this has gone right
$success = $results->execute();
$row = $results->fetch();
$html = $row[0];

$result = [
    'success' => $success,
    'html' => $html,
];

print json_encode($result);

JavaScript:

// You may now use the shorthand
$.post('process.php', { text1: x }, function(response) {
    if (response.success) {
        $('#tooltip').text(response.html);
    } else {
        ... show error ...
    }
});

answered May 17, 2016 at 12:10

Raphioly-San's user avatar

For simple transfer of data from PHP to AJAX, Json encoding or key value pairs are not always necessary. It can be simply done using string handling.

A sample code explaining this functionality is below.

    $query = "SELECT email FROM login WHERE email = '". mysqli_real_escape_string($conn,$email) ."' AND password = '". mysqli_real_escape_string($conn,$pass) ."'" ;

    $result = mysqli_query($conn,$query);
    $row=mysqli_fetch_row($result);

    $row_cnt = mysqli_num_rows($result);
    $s_email = $row[0];

    if ($row_cnt == 1) {
        $response="success";
    } else {
    $response = "Invalid Credentials";
    }

    $conn->close();

    $_SESSION["email"]= $s_email;
    echo $response;

This code shows how a ‘success’ response is sent back to ajax calling the php code. Further in ajax the following could be done to retrieve the response.

    $.ajax({ type : 'POST',
          data : {email: $('#email').val(), password: $('#pass').val()},
          url  : 'login.php',              
          success: function (data) {
            if(data == 'success'){  //the value echoed from php can be stored in the data variable of ajax
                window.location.assign('upload.php');
            }
            else{
                alert(data);
            }
          },
          error: function ( xhr ) {
            alert("error");
        }
    });

The above concept can be extended to return MULTIPLE VALUES also. This method allows simple tranfer of data from PHP to AJAX in a string format.

We have to follow a simple step of echoing everything we need to send as a response from the php to ajax, seperated by a unique seperator.

    echo $response.#;
    echo $email.#;
    echo $password.#;
    echo "Hello".#;
    echo "World";

Then the variable data in ajax could be simply retrieved as in the above example and a simple function like,

    var res = data.split("#");

data, being the variable within ajax.
The res array can then be used within js for whatever purpose we need.

First, I start from the server-side.

Since you want to submit the form via XHR request, the server should return the data as a JSON object.

Using JSON, you could have a structured data containing result and probable errors.

So, in your PHP file to which the form will send the request:

# Check whether the validation was successful
if ($validated === true) {
    # Do your logic...
    # Insert the posted data into database... etc.

    # show success message
    $response = array(
        'error'  => null,
        'result' => array(
            'message' => "Successfully message..."
        )
    );        
} else {
    # Show the error message
    $response = array(
        # In this case, get_readable_errors() method returns an array
        # which contains the 'name' of the invalid fields as key
        # and the validation error as value
        # e.g.
        #
        # 'error' = array(
        #     'name'    => 'Validation error for name field',
        #     'comment' => 'Validation error for comment field'
        # ),
        'error' => $validator->get_readable_errors(),
        'result' => null
    );
}

# send the output as JSON
echo json_encode($response);

Then, at the client-side, you need to prevent the default submission of the form.

Using jQuery, you could use .submit() method to bind a handler to the submit event:

var $form = $('#myForm'),

_updateView = function(data, $form) {
    data.error === null             &&
    _showResult(data.result, $form) ||
    _showError(data.error, $form);
},

// This function triggers if the ouput data has no error
_showResult = function(result, $form) {

    // Clear all error messages
    // Remove the old success message
    // Insert the Success message
    // Reset the form
    $form[0].reset();

    return true;
},

// This function triggers if the output is an error
_showError = function(error, $form) {
    // Clear old success message
    // Clear all old errors

    // Show the error message of each field
    $.each(error, function(field, err) {
        $('input[name="'+ field +'"]')
            .addClass('error')
            // Insert the error message of the relevant field (optional)
            .after('<small class="error">'+ err +'</small>');
    });
};

The AJAX call, using $.ajax():

$form.submit(function(e) {
    /* Prevent the default submission */
    e.preventDefault();

    $.ajax({
        url      : 'PHP/file/URL',
        type     : 'POST',
        dataType : 'json',  /* <-- Parse the response as JSON object */
        data     : $form.serialize(),

        success: function(data) {
            // Update the view
            _updateView(data, $form);
        },

        error: function(jqXHR, textStatus, errorMessage) {
            console.log(errorMessage); // Optional
        }
    });
});

Hope this helps.

Update

I’ve just noticed your comment states:

I already do that with the client side validation. I want to use php
validation as well, if the client side fails (javascript disabled)

First, never rely on the client-side validating. The client can easily disable the JavaScript and POST the harmful data.

Second, since using AJAX is possible only if the JavaScript is enabled, if you need to push the PHP output in HTML format on non-AJAX requests, you could pass a ajax=true key/value pair to the server, and return the output as JSON to the view.

In $.ajax() method:

data : $form.serialize() + '&ajax=true',

Then check the existence and value of $_POST['ajax'] at the server-side and determine whether to send the output as JSON or not.

You could also determine the XHR request by checking the HTTP_X_REQUESTED_WITH in $_SERVER as follows:

function is_xhr_request()
{
    return ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
}

First, I start from the server-side.

Since you want to submit the form via XHR request, the server should return the data as a JSON object.

Using JSON, you could have a structured data containing result and probable errors.

So, in your PHP file to which the form will send the request:

# Check whether the validation was successful
if ($validated === true) {
    # Do your logic...
    # Insert the posted data into database... etc.

    # show success message
    $response = array(
        'error'  => null,
        'result' => array(
            'message' => "Successfully message..."
        )
    );        
} else {
    # Show the error message
    $response = array(
        # In this case, get_readable_errors() method returns an array
        # which contains the 'name' of the invalid fields as key
        # and the validation error as value
        # e.g.
        #
        # 'error' = array(
        #     'name'    => 'Validation error for name field',
        #     'comment' => 'Validation error for comment field'
        # ),
        'error' => $validator->get_readable_errors(),
        'result' => null
    );
}

# send the output as JSON
echo json_encode($response);

Then, at the client-side, you need to prevent the default submission of the form.

Using jQuery, you could use .submit() method to bind a handler to the submit event:

var $form = $('#myForm'),

_updateView = function(data, $form) {
    data.error === null             &&
    _showResult(data.result, $form) ||
    _showError(data.error, $form);
},

// This function triggers if the ouput data has no error
_showResult = function(result, $form) {

    // Clear all error messages
    // Remove the old success message
    // Insert the Success message
    // Reset the form
    $form[0].reset();

    return true;
},

// This function triggers if the output is an error
_showError = function(error, $form) {
    // Clear old success message
    // Clear all old errors

    // Show the error message of each field
    $.each(error, function(field, err) {
        $('input[name="'+ field +'"]')
            .addClass('error')
            // Insert the error message of the relevant field (optional)
            .after('<small class="error">'+ err +'</small>');
    });
};

The AJAX call, using $.ajax():

$form.submit(function(e) {
    /* Prevent the default submission */
    e.preventDefault();

    $.ajax({
        url      : 'PHP/file/URL',
        type     : 'POST',
        dataType : 'json',  /* <-- Parse the response as JSON object */
        data     : $form.serialize(),

        success: function(data) {
            // Update the view
            _updateView(data, $form);
        },

        error: function(jqXHR, textStatus, errorMessage) {
            console.log(errorMessage); // Optional
        }
    });
});

Hope this helps.

Update

I’ve just noticed your comment states:

I already do that with the client side validation. I want to use php
validation as well, if the client side fails (javascript disabled)

First, never rely on the client-side validating. The client can easily disable the JavaScript and POST the harmful data.

Second, since using AJAX is possible only if the JavaScript is enabled, if you need to push the PHP output in HTML format on non-AJAX requests, you could pass a ajax=true key/value pair to the server, and return the output as JSON to the view.

In $.ajax() method:

data : $form.serialize() + '&ajax=true',

Then check the existence and value of $_POST['ajax'] at the server-side and determine whether to send the output as JSON or not.

You could also determine the XHR request by checking the HTTP_X_REQUESTED_WITH in $_SERVER as follows:

function is_xhr_request()
{
    return ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
}

За последние 24 часа нас посетили 8780 программистов и 829 роботов. Сейчас ищут 363 программиста …


  1. smartCreate

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4

    Добрый день! Проблема следующая — осуществляю загрузку изображений на сайте пользователем. Само собой для загружаемого элемента существуют некоторые ограничения — расширение файла, вес, размер. Хочу сделать что бы посетитель видел отчет по каждой из причин если они возникли, то есть «Недопустимый тип»файла, «Превышен максимальный размер» и т.д.

    Форма выглядит таким образом:

    1. <form id=«feeds» method=«post» action=«<?php echo base_url(); ?>feeds/add_feeds» enctype=»multipart/form-data»>
    2.     <input type=«text» placeholder=«Заголовок статьи» name=«title» />
    3.     <input type=«text» placeholder=«Ключ статьи» name=«key_n» />
    4.     <input type=«file» name=«userfile» />
    5.     <button type=«submit» class=«button—8»>ОПУБЛИКОВАТЬ</button>

    Сервер:

    1.     $config[‘upload_path’] = ‘./library/img/news/’;
    2.     $config[‘allowed_types’] = ‘gif|jpg|png|jpeg’;
    3.     $config[‘max_size’]    = ‘100’;
    4.     $config[‘max_width’]  = ‘1024’;
    5.     $config[‘max_height’]  = ‘768’;
    6.     $config[‘encrypt_name’]    = TRUE;
    7.     $config[‘remove_spaces’] = TRUE;
    8.     $this->load->library(‘upload’, $config);
    9.     if ( ! $this->upload->do_upload()){
    10.         $error = array(‘error’ => $this->upload->display_errors());
    11.         $this->load->view(‘pages/feeds/index’, $error);
    12.         $image_data = $this->upload->data();
    13.         $feeds[‘title’]  = $_POST[‘title’];
    14.         $feeds[‘txt’] = $_POST[‘txt’];
    15.         $feeds[‘key_n’] = $_POST[‘key_n’];
    16.         $feeds[‘img’] = $image_data[‘file_name’];
    17.         $this->main_model->new_feeds($feeds);

    Сервер написан на php-фреймворке Codignaiter, обработка и отображение ошибок происходит вот в этой части кода:

    1. if ( ! $this->upload->do_upload()){
    2.     $error = array(‘error’ => $this->upload->display_errors());
    3.     $this->load->view(‘pages/feeds/index’, $error);

    Для того что бы ошибка отображалась на страницу добавляю вот это:

    1. <?php if (isset($error)) {?>

    И если на форму не вешать аякс, что бы отправка на сервер происходила обновлением страницы, то вывод ошибок будет работать, а вот если повесить аякс, то нет…
    Конечно, в скрипте можно вывести какой-то allert с ошибкой типа «Что-то пошло не так», но это не совсем то что я хочу, обработчтк выглядит так:

    1. $(«form#feeds»).submit(function(e){
    2.         form = new FormData(this),
    3.         s = $(f.elements).last(),
    4.         e = s.end().slice(0, 2).removeClass(‘input-error’).filter(function() {
    5.             return !$.trim(this.value)
    6.     if(e.length) e.addClass(‘input-error’);
    7.             success: function(data) {
    8.                 e.removeClass(‘input-error’);
    9.                 $(«#content»).load(«feeds #content»);

    Я догадываюсь что мне каким-то образом нужно вывести вот это:

    1. <?php if (isset($error)) {?>

    здесь:

    Но, как это сделать я не понимаю, и не могу найти адекватного ответа в интернете, прошу помочь, словом или делом))


  2. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    А в чем, собственно, проблема? Ты не знаешь, как аяксу ответ отдать, или что?
    Серверу плевать, кто его спрашивает. Он так же отдает ответ. Тебе надо просто его обработать. Отдавай в виде JSON, тогда любую структуру данных без проблем упакуешь-распакуешь.


  3. smartCreate

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4

    Именно так…, не знаю, если не сложно, подскажи пожалуйста, некогда раньше не сталкивался(


  4. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Для сервера запрос от аякса — это такой же запрос от браузера. Он его просто обрабатывает. И просто отдает в ответ. То есть у тебя в аякс приходит тот текст, что ты выплюнешь с сервера. Если это HTML, то там HTML. Но так не советую делать. Тебе лучше отдавать JSON с ошибкой, описанием и тд, а там уже доставать это значение на стороне JS и на страницу втыкать.


  5. smartCreate

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4

    Извини за туговатость, но у меня с синтаксисом еще плоховато из-а недостатка опыта, не мог бы помочь мне разобраться?

    Из того что ты сказал, я переделал скрипт на сервере вот таким образом:

    1.         $config[‘upload_path’] = ‘./library/img/news/’;
    2.         $config[‘allowed_types’] = ‘gif|jpg|png|jpeg’;
    3.         $config[‘max_size’]    = ‘500’;
    4.         $config[‘max_width’]  = ‘1024’;
    5.         $config[‘max_height’]  = ‘768’;
    6.         $config[‘encrypt_name’]    = TRUE;
    7.         $config[‘remove_spaces’] = TRUE;
    8.         $this->load->library(‘upload’, $config);
    9.         if ( ! $this->upload->do_upload()) exit (json_encode($error = array(‘error’ => $this->upload->display_errors())));{
    10.             $this->load->view(‘pages/feeds/index’, $error);
    11.             $image_data = $this->upload->data();
    12.             $feeds[‘title’]  = $_POST[‘title’];
    13.             $feeds[‘txt’] = $_POST[‘txt’];
    14.             $feeds[‘key_n’] = $_POST[‘key_n’];
    15.             $feeds[‘img’] = $image_data[‘file_name’];
    16.             $this->main_model->new_feeds($feeds);

    Не уверен что сделал правильно…, но в любом случаи не совсем понимаю как обработать результат в аяксе, опять же с синтаксисом разобраться не могу(


  6. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Тогда я тебе помочь не смогу. Синтаксис растолковывать, увы, у меня особо времени нет. Но могу дать совет — прежде чем вслепую сразу воротить что-то сложное, найди инфу по этому поводу, и собери что-нибудь простенькое, чтобы понимание пришло.

    Ну там..аяксовый скриптик, который раз в секунду обновляет циферку на экране. Пойми как это работает, и поймешь, как тебе сделать что-то сложное.


  7. smartCreate

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4

    Все не на столько плохо, я понимаю как работает аякс. До меня не как не дойдет, как условие правильно написать на сервере и как принять результат в error моего аякса, я просто банально с этим некогда не работал, даже не знаю как так вышло, но вышло. Я не прошу делать за меня или учить меня синтаксису, я просто не где не могу найти нормальную информацию, по моей проблеме. Если ты понимаешь что нужно, но нет времени объяснить или показать, скинь пожалуйста хоть материал какой-то — был бы невероятно благодарен


  8. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Вот и поработайте, на примере чего-то элементарного. Чтобы было не только теоретическое понимание, но и понимание механики процесса.
    Попробуйте один из примеров, лучше первый, с таймером. Он крайне наглядный. И сразу поймете, что вам делать дальше.


  9. marsik

    marsik
    Активный пользователь

    С нами с:
    30 дек 2008
    Сообщения:
    246
    Симпатии:
    17

    наверное как-то так:

    1. $(«#result»).text(‘некая ошибка’); //показываем ошибку на странице, например в <p id=»result»></p>


  10. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Нет. Ни то ни то. error — это если произошла реальная ошибка. Ошибка же автора приходит с кодом 200, это вполне корректный ответ сервера. Это не ошибка выполнения или запроса, это просто серверу не нравится контент, который ему передали. Результат этого запроса будет передан в success.


  11. marsik

    marsik
    Активный пользователь

    С нами с:
    30 дек 2008
    Сообщения:
    246
    Симпатии:
    17

    Ну он же получает данные в data, туда и передавать данные, типа

    1. if(data.myerror) $(«#result»).text(data.myerror);


  12. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Вы предлагаете ему делать это в обработчике error:function(), это неправильно и не будет работать. Код обработки должен быть в success:function(data);


  13. marsik

    marsik
    Активный пользователь

    С нами с:
    30 дек 2008
    Сообщения:
    246
    Симпатии:
    17

    Код обработки не обязательно должен быть в success:function(data) — То что ТС хочет сделать посредством php (существуют ограничения на расширение файла, вес, размер), можно проверить на js до отправки запроса через ajax


  14. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Безусловно. И можно и нужно. Больше предварительной валидации на клиенте — меньше холостых запросов к серверу.

    Но он хочет именно так. У него уже есть инфраструктура для этого, просто хочет синхрон на асинхрон поменять. Знаний JS нет. Есть знание жиквери-копипасты, но условное. Потом подрастет в плане навыков, перепишет по-правильному.


  15. smartCreate

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4

    Спасибо за столь активное внимание к моей теме) Дело на самом деле не в бездумном копипасте кодов джейквери. Просто есть такая штука как опыт, его мне вчера и не хватило, сегодня пол дня посидел и разобрался, вдруг кому нужно будет вот что вышло:

    1. // Условие в обработчике на сервере
    2. if ( ! $this->upload->do_upload()){
    3.         $image_data = $this->upload->data();
    4.         $feeds[‘title’]  = $_POST[‘title’];
    5.         $feeds[‘txt’] = $_POST[‘txt’];
    6.         $feeds[‘key_n’] = $_POST[‘key_n’];
    7.         $feeds[‘img’] = $image_data[‘file_name’];
    8.         $this->main_model->new_feeds($feeds);
    1. // Обработка полученного $error на клиенте
    2. success: function(data) {

    А проверяю я коректность отправляемого файла не на клиенте, не потому что делать нечего или не знаю как это сделать, а просто так уж вышло что в начале своего «пути» связался с фреймворком Codignaiter, а у этого засранца свои методы обработки и загрузки файлов, приходиться к ним приспосабливаться.

    Всем спасибо, тема закрыта ))


  16. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    А никто не говорит, что не надо ничего проверять на сервере. Надо, еще как. Обязательно надо. Мало ли кто и что будет нам пытаться загрузить, не используя браузер. Заливание шелла под видом картиночки — это ж классика.

    НО…при этом никто не мешает первичную проверку проводить на клиенте. Это благо для всех.
    1) Клиент сразу узнаёт, что что-то не так. Ему не надо ждать, пока файл загрузится и прожуется сервером. Жители отдаленных регионов и севера скажут огромное спасибо.
    2) Серверу не надо впустую грузить файлы и проверять их. Да, все равно могут валидацию отключить на клиенте и сунуть всякое, но…это один из тысячи. И тут серверная проверка отработает как надо. А остальные 999 из тысячи некорректных запросов и вовсе не дойдут до сервера. Пусть он лучше тратит свои ресурсы на полезную нагрузку.


  17. smartCreate

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4

    Спасибо конечно) я это обязательно учту, хотя я это все и раньше знал/понимал, но повторение -мать учение, по этому спасибо что не поленился написать это разъяснение. Вопрос просто изначально не в целесообразности валидации на сервере был, а в том как ошибку при этой самой валидации показать клиенту


  18. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Понятное дело, но мы же беседуем. Беседа дошла до проблемы валидации, которой не все уделяют должное внимание. Более того, твоя серверная валидация с аяксом никак не исключает клиентскую поверх. Для пользователя будет выглядеть одинаково, если одинаково обыграешь в коде.

Примеры использования плагина Ajax Simply (ajaxs). Документацию смотрите по этой ссылке.

#1 Возврат из PHP (echo)

Этот пример показывает, как в PHP функции обработчике мы можем просто вывести HTML на экран и JS его в результате получит…

<!-- HTML -->
<div class="contact"></div>
// JS
ajaxs( 'ajaxs_get_email', { email: 'foo@gmail.com' }, function( html ){
	$('.contact').html( html );
} );
<?php
function ajaxs_get_email( $jx ){
	?>
	<p class="myclass"><?php echo esc_html( $jx->email ) ?></p>
	<?php

	// одновременно выведем данные в консоль
	$jx->console( $jx->email );
}

#1.2 Возврат из PHP (return)

Допустим нам нужно обработать принятые данные в PHP и вернуть объект данных в JS:

<!-- HTML -->
<div class="my_form">
	<label><input type="checkbox" name="my_check" /> мой чекбокс </label>
	<select name="my_select">
		<option>Опция 1</option>
		<option>Опция 2</option>
	</select>
</div>
// JS
ajaxs( 'ajaxs_parse_form', $('.my_form'), function( data ){

	data.done;  //> true
	data.check; //> 'on' если чекбокс выделен
	data.sel;   //> 'Опция 1' или 'Опция 2'

} );
<?php
function ajaxs_parse_form( $jx ){
	return array(
		'check' => $jx->my_check,
		'sel'   => $jx->my_select,
		'done'  => true,
	);
}

Вернуть можно что угодно: объект/массив/число/строку/true/false. В этом примере возвращается массив.

#1.3 Возврат из PHP ($jx->done|error)

Методы $jx->done(), $jx->error() — отправляют объект и обрывают работу PHP. Это аналоги функций wp_send_json_success() и wp_send_json_error().

<!-- HTML -->
<div class="ajax-respond"></div>
// JS
ajaxs( 'my_function', function( res ){
	var $respond = jQuery('.ajax-respond');

	// успех
	if( res.ok ){
		// сработал метод $jx->done()
		$respond.html( 'УСПЕХ:' + res.data );
	}

	// ошибка
	if( res.error ) {
		// сработал метод $jx->error()
		$respond.html( 'ОШИБКА:' + res.data );
	}
} );
// PHP
// префикс 'ajaxs_priv_' означает, что функция сработает только для авторизованного в WP пользователя
function ajaxs_priv_my_function( $jx ){
	// какие-либо првоерки
	if( условие не выполняется ){
		$jx->error( 'описание ошбики' );
	}

	if( дургое условие не выполняется ){
		$jx->error( 'описание ошбики' );
	}

	$jx->done( 'Все проверки пройдены!' );

	// этот код выполнен не будет, потому что $jx->error() или $jx->done() обрывают работу PHP.
	echo 'строка которая не будет выведена';
}

#2 PHP функция-обработчик (function)

Этот пример показывает как указать какая функция PHP будет обрабатывать запрос.

// JS
ajaxs( 'my_function' );
// PHP

// вариант: префикс 'ajaxs_' - для всех юзеров
function ajaxs_my_function( $jx ){
	$jx->log( 'Сработал запрос с action = my_function' );
}

// вариант: префикс 'ajaxs_priv_' - только для авторизованных
function ajaxs_priv_my_function( $jx ){
	$jx->log( 'Сработал запрос с action = my_function' );
}

#2.2 PHP функция-обработчик (static method)

Этот пример показывает как указать статический метод класса, который будет обрабатывать запрос.

// JS
ajaxs( 'MY_Class::my_method' );
// PHP
class MY_Class {

	static function ajaxs_my_method( $jx ){
		$jx->console( 'Сработал метод: '. __METHOD__ );
	}

}

Или так

// PHP
class AJAXS_MY_Class {

	static function my_method( $jx ){
		$jx->console( 'Сработал метод: '. __METHOD__ );
	}

}

Обратите внимание на обязательные префиксы AJAXS_ у класса или ajaxs_ у метода.

Эти префиксы для понятности можно указать в вызываемой функции:

// JS
ajaxs( 'AJAXS_MY_Class::my_method' );

#2.3 PHP функция-обработчик (namespace)

Этот пример показывает как указать статический метод класса, который находится в пространстве имен myspace.

// JS
ajaxs( '\myspace\AJAXS_Class::method' )
// PHP
namespace myspace;

class AJAXS_Class {

	static function method( $jx ){
		$jx->console( 'Сработал метод: '. __METHOD__ );
	}

}

#2.4 PHP функция-обработчик (hook)

Этот пример показывает как указать обработчик используя стандартный хук WordPress.

// JS
ajaxs( 'my_action_name' );
// PHP
// вариант с хуком - как обычно в wordpress
add_action( 'wp_ajax_'.'my_action_name', 'ajax_my_action_name_handler' );
add_action( 'wp_ajax_nopriv_'.'my_action_name', 'ajax_my_action_name_handler' );

function ajax_my_action_name_handler( $jx ){
	$jx->log( 'Сработал запрос с action = my_function' );
}

Обратная совместимость c хуками WordPress дает возможность установить плагин и не переделывать уже написанный PHP код и при этом использовать функцию ajaxs() в JS. «Старый» PHP код будет работать как и до этого…

#3 AJAX Загрузка файлов (single)

<!-- HTML -->
<div class="form">
	<input type="file" name="file_single" />
</div>
// JS
// вариант: передача всей формы
ajaxs( 'upload_image', jQuery('.form') );

// вариант: передача file поля
ajaxs( 'upload_image', jQuery('[input name="file_single"]') );

// вариант: передача значения поля
var file = jQuery('[input name="file_single"]')[0].files[0];
ajaxs( 'upload_image', { file_single: file } );
// PHP
function ajaxs_upload_image( $jx ){
	$file = $jx->file_single;
	/* $file будет содержать:
	Array (
		[name]     => Alex-Lynn.jpg
		[type]     => image/jpeg
		[tmp_name] => /home/server/userdata/temp/phpEB56.tmp
		[error]    => 0
		[size]     => 34986
	)
	*/

	// обрабатываем полученный файл
}

#3.2 AJAX Загрузка файлов (multiple)

Передать несколько файлов можно в одном поле file или в нескольких. Рассмотрим оба варианта в примере:

<!-- HTML -->
<div class="files-upload-form">
	<p><input type="file" multiple="multiple" name="file_multiple[]" /> - множественный выбор файлов</p>

	<p><input type="file" name="file_split_multiple[]" /> - выбор одного файла</p>
	<p><input type="file" name="file_split_multiple[]" /> - выбор одного файла</p>
</div>
// JS
ajaxs( 'upload_image', jQuery('.files-upload-form') );
// PHP
function ajaxs_upload_image( $jx ){

	// обе переменные будут содержать одинаковый формат - стандарт PHP
	$jx->file_multiple;
	$jx->file_split_multiple;

	/*
	Array (
		[name] => Array (
				[0] => Alex-Lynn.jpg
				[1] => caliyan.jpg
			)

		[type] => Array (
				[0] => image/jpeg
				[1] => image/jpeg
			)

		[tmp_name] => Array (
				[0] => /home/server/userdata/temp/phpBA7C.tmp
				[1] => /home/server/userdata/temp/phpBA8D.tmp
			)

		[error] => Array (
				[0] => 0
				[1] => 0
			)

		[size] => Array (
				[0] => 34986
				[1] => 178154
			)
		[compact] => Array (
				[0] => Array (
					[name]     => Alex-Lynn.jpg
					[type]     => image/jpeg
					[tmp_name] => /home/server/userdata/temp/phpBA7C.tmp
					[error]    => 0
					[size]     => 34986
				)

				[1] => Array (
					[name]     => caliyan.jpg
					[type]     => image/jpeg
					[tmp_name] => /home/server/userdata/temp/phpBA8D.tmp
					[error]    => 0
					[size]     => 178154
				)
			)

	)
	*/

	// обрабатываем полученные файлы
}

ЗАМЕТКА: Обратите внимание на индекс compact он добавляется плагином для удобства обработки данных. С версии 1.1.9.

#3.3 AJAX Загрузка файлов (прогресс загрузки)

Этот пример показывает, как уведомлять пользователя о загрузке файла (сколько процентов файла уже загружено). Для этого используется параметр uploadProgress, в который нужно передать функцию, которая должна выводить куда-то полученный прогресс загрузки.

Для упрощения, PHP обработка запроса в примере не показана.

<!-- HTML -->
<form id="my_form">
	<input type="file" name="attached_file">

	<button type="submit">Send mail</button>
	<span class="file_upload_progress" ></span>
</form>
// JS
var data = {
	foo : jQuery('#my_form'),
	uploadProgress : function( percentComplete ){
		// выведем прогресс в HTML элемент .file_upload_progress
		jQuery('.file_upload_progress').text( percentComplete + '%' );
	}
};
ajaxs( 'upload_image', data );

#4 Использование $jx->html()

Допустим у нас есть контейнер, в который нужно вывести форму авторизации, такую форму легко получить с помощью функции wp_login_form().

<!-- HTML -->
<a class="auth_form_btn" href="#">Показать форму входа</a>
<div class="auth_form" style="display:none;"></div>
jQuery(function($){

	$('.auth_form_btn').click(function(ev){
		ev.preventDefault();

		ajaxs( 'show_auth_form' );
	});

});
function ajaxs_show_auth_form( $jx ){

	// добавим HTML в блок .auth_form
	$jx->html( '.auth_form', wp_login_form([ 'echo'=>false ]) );

	// покажем блок
	$jx->jseval( "jQuery('.auth_form').show();" );
}

Создавать JS код в PHP не очень правильно, но иногда это очень удобно!

#5 Показ PHP ошибок

В WordPress показ ошибок для AJAX запросов полностью отключен и увидеть их можно только через лог файл. Это очень неудобно! Кто сталкивался, знает о чем я…

AJAX Simply выводит ошибки любого уровня в консоль, даже если это фатальная ошибка. Вывод ошибок работает только при включенном WP_DEBUG, поэтому не стоит беспокоится, что обычные пользователи могут увидеть ошибки или заметки, ведь на рабочем проекте WP_DEBUG отключен.

Для примера представим, что мы обрабатываем AJAX запрос и допустили фатальную ошибку, например, неправильно написали название какой-нибудь функции.

// JS
ajaxs( 'phpfunction' );
// PHP
function ajaxs_phpfunction( $jx ){
	// переменная, которой нет (ошибка уровня notice)
	$var['key'];

	// функция, которой нет в PHP (ошибка уровня fatal error)
	error_function_name();
}

В результате при AJAX запросе увидим ошибки в консоли браузера, а не будем гадать что же произошло и тратить свое время на поиск причины:

Тут важно отметить, что плагин ловит ошибки с ранней стадии — с момента как подключился его главный файл. Так например, если есть ошибка в файле functions.php он её поймает и выведет в консоль.

В идеале, плагин лучше устанавливать в MU плагины, правда там не будут работать автообновление.

#6 Пример обработчика для отправки письма с файлами

<?php

function ajaxs_mailer( $jx ){

	$attached_files = [];

	if( $jx->files ){

		$files = $jx->files[ 'compact' ];

		if( count( $files ) > 5 ){
			$jx->error( [
				'type'    => 'failCount',
				'message' => sprintf(
					__( 'Максимальное количество файлов - 5, вы пытаетесь отправить %d', 'amcor' ),
					count( $files )
				),
			] );
		}

		foreach( $files as $file ){

			$allowedTypes = [
				'image/jpeg',
				'image/png',
				'application/pdf',
				'application/msword',
				'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
				'application/vnd.ms-excel',
				'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
			];

			$maxSize = 10 * 1024 * 1024;

			if( $file[ 'size' ] > $maxSize ){
				$jx->error( [
					'type'    => 'failSize',
					'message' => sprintf(
						__( 'Максимально допутимый размер одного файла для загрузки - %d Мб. Размер файла %s - %d Мб', 'amcor' ),
						$maxSize / ( 1024 * 1024 ),
						$file[ 'name' ],
						$file[ 'size' ] / ( 1024 * 1024 )
					),
				] );
			}

			if( ! in_array( $file[ 'type' ], $allowedTypes ) ){
				$jx->error( [
					'type'    => 'failType',
					'message' => sprintf(
						__( 'Ошибка загрузки файла %s Допускаются только файлы формата .jpg, .png, .pdf, .doc, .docx, .xls, .xslx', 'amcor' ),
						$file[ 'name' ]
					),
				] );
			}

			if( $file && ! $file[ 'error' ] ){
				$attached_file_path = dirname( $file[ 'tmp_name' ] ) . '/' . sanitize_file_name( $file[ 'name' ] );
				@rename( $file[ 'tmp_name' ], $attached_file_path );
				$attached_files[] = $attached_file_path;
			}

		}
	}

	$to      = 'palov@gmail.com';
	$subject = 'Новая заявка с сайта';

	$message = "
	<strong>Имя:</strong> $jx->name<br>
	<strong>E-mail:</strong> $jx->email<br>
	<strong>Телефон:</strong> $jx->phone<br><br>
	";

	$headers = [ 'content-type: text/html' ];

	//$jx->log( $attached_files );

	$sent = wp_mail( $to, $subject, $message, $headers, $attached_files );

	if( $attached_files ){
		foreach( $attached_files as $_file ){
			@unlink( $_file );
		}
	}

	if( $sent )
		$jx->done( __( 'Ваш запрос успешно отправлен!', 'amcor' ) );
	else
		$jx->error( __( 'Ошибка при отправке запроса.', 'amcor' ) );

}

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Вывод ошибок mysql php
  • Вывод ошибки mysql query