WordPress.org

Make WordPress Core


Ignore:
Timestamp:
10/28/2014 06:34:16 PM (6 years ago)
Author:
pento
Message:

Add wp_json_encode(), a wrapper for json_encode() that ensures everything is converted to UTF-8.

Change all core calls from json_encode() to wp_json_encode().

Fixes #28786.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/functions.php

    r29915 r30055  
    26142614
    26152615/**
     2616 * Encode a variable into JSON, with some sanity checks
     2617 *
     2618 * @since 4.1.0
     2619 *
     2620 * @param mixed $data    Variable (usually an array or object) to encode as JSON
     2621 * @param int   $options Options to be passed to json_encode(). Default 0.
     2622 * @param int   $depth   Maximum depth to walk through $data. Must be greater than 0, default 512.t
     2623 *
     2624 * @return bool|string The JSON encoded string, or false if it cannot be encoded
     2625 */
     2626function wp_json_encode( $data, $options = 0, $depth = 512 ) {
     2627    // json_encode has had extra params added over the years.
     2628    // $options was added in 5.3, and $depth in 5.5.
     2629    // We need to make sure we call it with the correct arguments.
     2630    if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {
     2631        $args = array( $data, $options, $depth );
     2632    } else if ( version_compare( PHP_VERSION, '5.3', '>=' ) ) {
     2633        $args = array( $data, $options );
     2634    } else {
     2635        $args = array( $data );
     2636    }
     2637
     2638    $json = call_user_func_array( 'json_encode', $args );
     2639
     2640    if ( false !== $json ) {
     2641        // If json_encode was successful, no need to do more sanity checking
     2642        return $json;
     2643    }
     2644
     2645    try {
     2646        $args[0] = _wp_json_sanity_check( $data, $depth );
     2647    } catch ( Exception $e ) {
     2648        return false;
     2649    }
     2650
     2651    return call_user_func_array( 'json_encode', $args );
     2652}
     2653
     2654/**
     2655 * @ignore
     2656 */
     2657function _wp_json_sanity_check( $data, $depth ) {
     2658    if ( $depth < 0 ) {
     2659        throw new Exception( 'Reached depth limit' );
     2660    }
     2661
     2662    if ( is_array( $data ) ) {
     2663        $output = array();
     2664        foreach ( $data as $id => $el ) {
     2665            // Don't forget to sanitize the ID!
     2666            if ( is_string( $id ) ) {
     2667                $clean_id = _wp_json_convert_string( $id );
     2668            } else {
     2669                $clean_id = $id;
     2670            }
     2671
     2672            // Check the element type, so that we're only recursing if we really have to
     2673            if ( is_array( $el ) || is_object( $el ) ) {
     2674                $output[ $clean_id ] = _wp_json_sanity_check( $el, $depth - 1 );
     2675            } else if ( is_string( $el ) ) {
     2676                $output[ $clean_id ] = _wp_json_convert_string( $el );
     2677            } else {
     2678                $output[ $clean_id ] = $el;
     2679            }
     2680        }
     2681    } else if ( is_object( $data ) ) {
     2682        $output = new stdClass;
     2683        foreach ( $data as $id => $el ) {
     2684            if ( is_string( $id ) ) {
     2685                $clean_id = _wp_json_convert_string( $id );
     2686            } else {
     2687                $clean_id = $id;
     2688            }
     2689
     2690            if ( is_array( $el ) || is_object( $el ) ) {
     2691                $output->$clean_id = _wp_json_sanity_check( $el, $depth - 1 );
     2692            } else if ( is_string( $el ) ) {
     2693                $output->$clean_id = _wp_json_convert_string( $el );
     2694            } else {
     2695                $output->$clean_id = $el;
     2696            }
     2697        }
     2698    } else if ( is_string( $data ) ) {
     2699        return _wp_json_convert_string( $data );
     2700    } else {
     2701        return $data;
     2702    }
     2703
     2704    return $output;
     2705}
     2706
     2707/**
     2708 * @ignore
     2709 */
     2710function _wp_json_convert_string( $string ) {
     2711    static $use_mb = null;
     2712    if ( is_null( $use_mb ) ) {
     2713        $use_mb = function_exists( 'mb_convert_encoding' );
     2714    }
     2715
     2716    if ( $use_mb ) {
     2717        $encoding = mb_detect_encoding( $string, mb_detect_order(), true );
     2718        if ( $encoding ) {
     2719            return mb_convert_encoding( $string, 'UTF-8', $encoding );
     2720        } else {
     2721            return mb_convert_encoding( $string, 'UTF-8', 'UTF-8' );
     2722        }
     2723    } else {
     2724        return wp_check_invalid_utf8( $data, true );
     2725    }
     2726}
     2727
     2728/**
    26162729 * Send a JSON response back to an Ajax request.
    26172730 *
     
    26232736function wp_send_json( $response ) {
    26242737    @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
    2625     echo json_encode( $response );
     2738    echo wp_json_encode( $response );
    26262739    if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
    26272740        wp_die();
Note: See TracChangeset for help on using the changeset viewer.