Поддержка Проблемы и решения The function wpdb::prepare does not warn of an error

  • Решено karpo518

    (@karpo518)


    I am developing a plugin and encountered a bug while executing a sql query. An incorrect number of parameters was passed to the wpdb::prepare service. I had debug enabled and saw a warning. Fortunately, the warning specified the function where the error occurred. I took a quick look at the code of the wpdb::prepare function and noticed that it returns an empty value when there are errors. I rewrote my database code and added a check of the returned value. I reproduced the problem and found that my code could not identify the problem. Then I took a close look at the code of the wpdb::prepare function once again. It turned out that it didn’t always return an empty value in case of an error. Sometimes the function is limited by a warning. This warning is triggered only if W_DEBUG is enabled. The function doesn’t allow you to check exactly if its result is successful.

    I’m very lucky to have detected the error in advance and was able to reproduce it. I added custom time code inside the wpdb::prepare function and displayed the parameters of the problem request. This allowed me to fix the problem.

    Imagine a situation where an error was found on a production site. WP_DEBUG is off. The user detects the problem and asks me to fix it. I look into the plugin’s operation log and see nothing. I can’t see either the function that caused the bug or its parameters.

    Below I will enclose a fragment of the function that causes me questions. I’d like to ask community members to comment. Should the function ignore the mismatch between the number of placeholders and values and continue its execution? How right is it? I think, that if the function already has a value validation of the number values and placeholders, it should return an empty value in case of any errors.

    if ( count( $args ) !== $placeholders ) {
    			if ( 1 === $placeholders && $passed_as_array ) {
    				// If the passed query only expected one argument, but the wrong number of arguments were sent as an array, bail.
    				wp_load_translations_early();
    				_doing_it_wrong(
    					'wpdb::prepare',
    					__( 'The query only expected one placeholder, but an array of multiple placeholders was sent.' ),
    					'4.9.0'
    				);
    
    				return;
    			} else {
    				/*
    				 * If we don't have the right number of placeholders, but they were passed as individual arguments,
    				 * or we were expecting multiple arguments in an array, throw a warning.
    				 */
    				wp_load_translations_early();
    				_doing_it_wrong(
    					'wpdb::prepare',
    					sprintf(
    						/* translators: 1: Number of placeholders, 2: Number of arguments passed. */
    						__( 'The query does not contain the correct number of placeholders (%1$d) for the number of arguments passed (%2$d).' ),
    						$placeholders,
    						count( $args )
    					),
    					'4.8.3'
    				);
    			}
    		}
    
    		array_walk( $args, array( $this, 'escape_by_ref' ) );
    		$query = vsprintf( $query, $args );
    
    		return $this->add_placeholder_escape( $query );
    • Тема изменена 2 года назад пользователем karpo518.
Просмотр 1 ответа (всего 1)
Просмотр 1 ответа (всего 1)
  • Тема «The function wpdb::prepare does not warn of an error» закрыта для новых ответов.