admin管理员组

文章数量:1122826

Please help me edit the code so that wordpress does not change the & symbol to #038 when I publish links on my site

function esc_url( $url, $protocols = null, $_context = 'display' ) {
$original_url = $url;

if ( '' === $url ) {
    return $url;
}

$url = str_replace( ' ', '%20', ltrim( $url ) );
$url = preg_replace( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url );

if ( '' === $url ) {
    return $url;
}

if ( 0 !== stripos( $url, 'mailto:' ) ) {
    $strip = array( '%0d', '%0a', '%0D', '%0A' );
    $url   = _deep_replace( $strip, $url );
}

$url = str_replace( ';//', '://', $url );
/*
 * If the URL doesn't appear to contain a scheme, we presume
 * it needs http:// prepended (unless it's a relative link
 * starting with /, # or ?, or a PHP file).
 */
if ( ! str_contains( $url, ':' ) && ! in_array( $url[0], array( '/', '#', '?' ), true ) &&
    ! preg_match( '/^[a-z0-9-]+?\.php/i', $url )
) {
    $url = 'http://' . $url;
}

// Replace ampersands and single quotes only when displaying.
if ( 'display' === $_context ) {
    $url = wp_kses_normalize_entities( $url );
    $url = str_replace( '&', '&', $url );
    $url = str_replace( "'", ''', $url );
}

if ( str_contains( $url, '[' ) || str_contains( $url, ']' ) ) {

    $parsed = wp_parse_url( $url );
    $front  = '';

    if ( isset( $parsed['scheme'] ) ) {
        $front .= $parsed['scheme'] . '://';
    } elseif ( '/' === $url[0] ) {
        $front .= '//';
    }

    if ( isset( $parsed['user'] ) ) {
        $front .= $parsed['user'];
    }

    if ( isset( $parsed['pass'] ) ) {
        $front .= ':' . $parsed['pass'];
    }

    if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) {
        $front .= '@';
    }

    if ( isset( $parsed['host'] ) ) {
        $front .= $parsed['host'];
    }

    if ( isset( $parsed['port'] ) ) {
        $front .= ':' . $parsed['port'];
    }

    $end_dirty = str_replace( $front, '', $url );
    $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty );
    $url       = str_replace( $end_dirty, $end_clean, $url );

}

if ( '/' === $url[0] ) {
    $good_protocol_url = $url;
} else {
    if ( ! is_array( $protocols ) ) {
        $protocols = wp_allowed_protocols();
    }
    $good_protocol_url = wp_kses_bad_protocol( $url, $protocols );
    if ( strtolower( $good_protocol_url ) !== strtolower( $url ) ) {
        return '';
    }
}

Please help me edit the code so that wordpress does not change the & symbol to #038 when I publish links on my site

function esc_url( $url, $protocols = null, $_context = 'display' ) {
$original_url = $url;

if ( '' === $url ) {
    return $url;
}

$url = str_replace( ' ', '%20', ltrim( $url ) );
$url = preg_replace( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url );

if ( '' === $url ) {
    return $url;
}

if ( 0 !== stripos( $url, 'mailto:' ) ) {
    $strip = array( '%0d', '%0a', '%0D', '%0A' );
    $url   = _deep_replace( $strip, $url );
}

$url = str_replace( ';//', '://', $url );
/*
 * If the URL doesn't appear to contain a scheme, we presume
 * it needs http:// prepended (unless it's a relative link
 * starting with /, # or ?, or a PHP file).
 */
if ( ! str_contains( $url, ':' ) && ! in_array( $url[0], array( '/', '#', '?' ), true ) &&
    ! preg_match( '/^[a-z0-9-]+?\.php/i', $url )
) {
    $url = 'http://' . $url;
}

// Replace ampersands and single quotes only when displaying.
if ( 'display' === $_context ) {
    $url = wp_kses_normalize_entities( $url );
    $url = str_replace( '&', '&', $url );
    $url = str_replace( "'", ''', $url );
}

if ( str_contains( $url, '[' ) || str_contains( $url, ']' ) ) {

    $parsed = wp_parse_url( $url );
    $front  = '';

    if ( isset( $parsed['scheme'] ) ) {
        $front .= $parsed['scheme'] . '://';
    } elseif ( '/' === $url[0] ) {
        $front .= '//';
    }

    if ( isset( $parsed['user'] ) ) {
        $front .= $parsed['user'];
    }

    if ( isset( $parsed['pass'] ) ) {
        $front .= ':' . $parsed['pass'];
    }

    if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) {
        $front .= '@';
    }

    if ( isset( $parsed['host'] ) ) {
        $front .= $parsed['host'];
    }

    if ( isset( $parsed['port'] ) ) {
        $front .= ':' . $parsed['port'];
    }

    $end_dirty = str_replace( $front, '', $url );
    $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty );
    $url       = str_replace( $end_dirty, $end_clean, $url );

}

if ( '/' === $url[0] ) {
    $good_protocol_url = $url;
} else {
    if ( ! is_array( $protocols ) ) {
        $protocols = wp_allowed_protocols();
    }
    $good_protocol_url = wp_kses_bad_protocol( $url, $protocols );
    if ( strtolower( $good_protocol_url ) !== strtolower( $url ) ) {
        return '';
    }
}
Share Improve this question asked Apr 6, 2024 at 12:23 JamesJames 1 0
Add a comment  | 

1 Answer 1

Reset to default 0

esc_url() has a $_context argument which defaults to 'display'. It will replace & with & unless you change context to something else, e.g. sanitize_url uses 'db'. (Why it uses & instead of the usual & I don't understand, but it's deliberate.)

I'm guessing you're calling esc_url() somewhere in your code where you should be calling esc_url_raw() or sanitize_url() (which are identical) instead. These will not substitute &s.

本文标签: php038 amp wordpress Help