Biến URL thành Tệp đính kèm / ID bài


32

Có cách nào tôi có thể lấy URL của một hình ảnh và tìm tệp đính kèm hoặc id bài đăng của hình ảnh đó trong cơ sở dữ liệu không?

Đây là tình huống:

Tôi đang trong một vòng lặp đi qua tất cả các thẻ 'img' được bao quanh bởi các thẻ 'a' trong nội dung bài đăng của tôi. nếu thuộc tính src của thẻ 'img' không khớp với thuộc tính href của thẻ 'a' bên ngoài, thì tôi muốn thay thế thẻ 'img'. Khi thực hiện điều này, nếu 'img' cần xóa trong thư viện, tôi muốn xóa bài đăng đó, rồi đặt 'img' thay thế vào vị trí của nó. Tôi đã thử sử dụng một chức năng như thế này:

function find_image_post_id($url) {
  global $wpdb;
  $postid = $wpdb->get_var($wpdb->prepare("SELECT DISTINCT ID FROM $wpdb->posts WHERE guid='$url'"));
  if ($postid) {
    return $postid;
  }
  return false;
}

Điều này rõ ràng là không đúng bởi vì hướng dẫn này thật trớ trêu không phải là duy nhất trên toàn cầu. Tôi đã (trước đó trong cùng một tập lệnh) đã tải lên một tệp có cùng tên (tại sao? Vì nó có độ phân giải cao hơn và tôi đang cố gắng thay thế các phiên bản có độ phân giải thấp của cùng một hình ảnh) và mặc dù wordpress sẽ lưu hình ảnh bằng một tên khác trong thư mục, hướng dẫn đã được thiết lập giống nhau. (có thể là một lỗi).

Có một kỹ thuật khác tôi có thể sử dụng?


Bạn có thể thiết lập các biến yêu cầu theo URL của mình, khởi tạo WP_Query và lấy thông tin từ nó.
hakre

Sẽ rất hữu ích nếu bạn có thể cập nhật câu hỏi của mình và đăng một số ví dụ về HTML bao gồm các URL bạn muốn thay thế để chúng tôi có thể thảo luận về chúng.
MikeSchinkel

Mike ở ngay đó. Là những hình ảnh lớn hơn mà bạn đang liên kết đến trên các trang web bên ngoài? Nếu không thì bạn chỉ cần chọn kích thước đầy đủ khi bạn thêm hình ảnh vào bài đăng của mình và bạn có tùy chọn không liên kết nó ở bất cứ đâu nếu nó không còn ý nghĩa nữa.
sanchothefat

Câu trả lời:


30

Chức năng cải tiến lớn được phát triển cho plugin nặng về hình ảnh:

if ( ! function_exists( 'get_attachment_id' ) ) {
    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   http://wordpress.stackexchange.com/a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    function get_attachment_id( $url ) {

        $dir = wp_upload_dir();

        // baseurl never has a trailing slash
        if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
            // URL points to a place outside of upload directory
            return false;
        }

        $file  = basename( $url );
        $query = array(
            'post_type'  => 'attachment',
            'fields'     => 'ids',
            'meta_query' => array(
                array(
                    'key'     => '_wp_attached_file',
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

        // query attachments
        $ids = get_posts( $query );

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                // first entry of returned array is the URL
                if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
                    return $id;
            }
        }

        $query['meta_query'][0]['key'] = '_wp_attachment_metadata';

        // query attachments again
        $ids = get_posts( $query );

        if ( empty( $ids) )
            return false;

        foreach ( $ids as $id ) {

            $meta = wp_get_attachment_metadata( $id );

            foreach ( $meta['sizes'] as $size => $values ) {

                if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
                    return $id;
            }
        }

        return false;
    }
}

1
Bạn có thể giải thích tại sao bạn truy vấn cả hai _wp_attached_file_wp_attachment_metadata?
Stephen Harris

3
@StephenHarris vì URL có thể trỏ đến bất kỳ kích thước nào của hình ảnh, tất cả đều có tên tệp khác nhau
Rarst

1
Điều này hoạt động rất tốt, nhưng điều đáng chú ý ở đây là, kể từ WordPress 4, có một chức năng tích hợp để làm điều đó như được đề cập bởi Gabriel trong một câu trả lời khác. Nó hoạt động chính xác như cách này.
Chris Rae

2
@ChrisRae nếu bạn nhìn vào nguồn, chức năng cốt lõi sẽ không hoạt động trên kích thước hình ảnh, chỉ trên hình ảnh chính.
Hết

Tôi nghĩ rằng chức năng tích hợp trong WordPress hoạt động tốt hơn. Điều này không hoạt động trong sản xuất của tôi nhưng đã hoạt động trên Staging (không có chứng chỉ SSL). Hàm tích hợp (như được chỉ ra bởi Ego Ipse bên dưới) hoạt động trong cả hai môi trường.
Syed Priom

15

Tất cả các hàm phức tạp đó có thể được giảm xuống thành một hàm đơn giản:

file đính kèm_url_to_postid ()

Bạn chỉ cần phân tích URL hình ảnh để lấy ID đính kèm:

$attachment_id = attachment_url_to_postid( $image_url );
echo $attachment_id;

Đó là tất cả những gì bạn cần.


6
Đáng chú ý là điều này sẽ không hoạt động trên kích thước hình ảnh, phiên bản lõi chỉ tìm kiếm tệp đính kèm "chính".
Hết

3

Tôi đã sửa đổi mã của Rarst để cho phép bạn chỉ khớp tên tệp thay vì đường dẫn đầy đủ. Điều này rất hữu ích nếu bạn chuẩn bị tải hình ảnh nếu nó không tồn tại. Hiện tại điều này chỉ hoạt động nếu tên tệp là duy nhất nhưng tôi sẽ thêm kiểm tra băm sau để trợ giúp với các hình ảnh có cùng tên tệp.

function get_attachment_id( $url, $ignore_path = false ) {

if ( ! $ignore_path ) {

    $dir = wp_upload_dir();
    $dir = trailingslashit($dir['baseurl']);

    if( false === strpos( $url, $dir ) )
        return false;
}

$file = basename($url);

$query = array(
    'post_type' => 'attachment',
    'fields' => 'ids',
    'meta_query' => array(
        array(
            'key'     => '_wp_attached_file',
            'value'   => $file,
            'compare' => 'LIKE',
        )
    )
);

$ids = get_posts( $query );

foreach( $ids as $id ) {
    $match = array_shift( wp_get_attachment_image_src($id, 'full') );
    if( $url == $match || ( $ignore_path && strstr( $match, $file ) ) )
        return $id;
}

$query['meta_query'][0]['key'] = '_wp_attachment_metadata';
$ids = get_posts( $query );

foreach( $ids as $id ) {

    $meta = wp_get_attachment_metadata($id);

    foreach( $meta['sizes'] as $size => $values ) {
        if( $values['file'] == $file && ( $ignore_path || $url == array_shift( wp_get_attachment_image_src($id, $size) ) ) )
            return $id;
    }
}

return false;
}

3

Ok tôi đã tìm thấy câu trả lời mà không ai có trên mạng mà tôi đang tìm kiếm nhiều ngày nay. Hãy mỏ này chỉ hoạt động nếu chủ đề hoặc plugin của bạn đang sử dụng WP_Customize_Image_Control()nếu bạn đang sử dụng WP_Customize_Media_Control()các get_theme_mod()sẽ trở lại ID và không phải là url.

Đối với giải pháp của tôi, tôi đã sử dụng phiên bản mới hơn WP_Customize_Image_Control()

Rất nhiều bài viết trên các diễn đàn có get_attachment_id()cái không còn hoạt động nữa. Tôi đã sử dụngattachment_url_to_postid()

Đây là cách tôi có thể làm điều đó. Hy vọng điều này sẽ giúp ai đó ngoài kia

// This is getting the image / url
$feature1 = get_theme_mod('feature_image_1');

// This is getting the post id
$feature1_id = attachment_url_to_postid($feature1);

// This is getting the alt text from the image that is set in the media area
$image1_alt = get_post_meta( $feature1_id, '_wp_attachment_image_alt', true );

Đánh dấu

<a href="<?php echo $feature1_url; ?>"><img class="img-responsive center-block" src="<?php echo $feature1; ?>" alt="<?php echo $image1_alt; ?>"></a>

0

Đây là một giải pháp thay thế:

$image_url = get_field('main_image'); // in case of custom field usage
$image_id = attachment_url_to_postid($image_url);

// retrieve the thumbnail size of our image
$image_thumb = wp_get_attachment_image_src($image_id, 'thumbnail');

Kể từ WP 4.0, họ đã giới thiệu một chức năng attachment_url_to_postid()hoạt động tương tự như của bạnfind_image_post_id()

Vui lòng kiểm tra url này để bạn tham khảo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.