这里是这种情况:
我在循环遍历我帖子内容中被“ a”标签包围的所有“ img”标签。如果'img'标签的src属性与外部'a'标签的href属性不匹配,那么我想替换'img'标签。为此,如果要删除的“ img”在图库中,我想删除该帖子,然后将替换的“ img”放在其位置。我尝试使用如下函数:
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;
}
这显然是不正确的,因为具有讽刺意味的是,guid并不是全局唯一的。我曾经(在同一脚本中使用较早版本)上传了一个具有相同名称的文件(为什么?因为分辨率更高,并且我试图替换同一图像的低分辨率版本),尽管wordpress会将图像保存为另一个名称在目录中,GUID设置为相同。 (可能是一个错误)。
还有其他可以使用的技术吗?
#1 楼
为大量图像插件开发的功能大大改进: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;
}
}
评论
您能否解释为什么同时查询_wp_attached_file和_wp_attachment_metadata?
–斯蒂芬·哈里斯(Stephen Harris)
2014年7月1日在22:11
@StephenHarris,因为URL可以指向任何具有不同文件名的图像大小
–稀有
2014年7月1日在22:14
这很好用,但是在这里值得注意的是,自WordPress 4起,就如Gabriel在另一个答案中提到的那样,有一个内置函数可以做到这一点。它的工作方式与此完全相同。
–克里斯·雷(Chris Rae)
16-09-27在23:21
@ChrisRae如果您查看源代码,则核心功能将不适用于图像尺寸,仅适用于主图像。
–稀有
16-09-28在8:48
@SyedPriom如果您正在搜索的URL与您存储的数据不一致,则它实际上将无法工作,这不是我在编写此文件时所考虑的事情,但可能会针对协议进行改进。如上所述,本机功能的主要问题是它不适用于图像尺寸。
–稀有
17年1月19日在8:25
#2 楼
所有这些复杂功能都可以简化为一个简单功能:attachment_url_to_postid()
您只需要解析图像URL即可检索附件ID:
$attachment_id = attachment_url_to_postid( $image_url );
echo $attachment_id;
这就是您所需要的。
评论
值得注意的是,这不适用于图像大小,核心版本仅搜索“主”附件。
–稀有
16-09-28在8:48
#3 楼
我修改了Rarst的代码,以允许您仅匹配文件名而不是完整路径。如果您要侧载图像(如果该图像不存在),这将很有帮助。当前,这仅在文件名唯一的情况下有效,但是我稍后将添加哈希检查以帮助处理具有相同文件名的图像。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;
}
#4 楼
好的,我找到了答案,这是我现在几天都在网上找不到的答案。请记住,这仅在主题或插件使用WP_Customize_Image_Control()
时有效,如果使用WP_Customize_Media_Control()
,则get_theme_mod()
将返回ID而不是URL。 对于我的解决方案,我使用的是较新版本的
WP_Customize_Image_Control()
论坛上的许多帖子都使用了
get_attachment_id()
,该版本不再起作用。我使用了attachment_url_to_postid()
这就是我的方法。希望这对外面的人有帮助
#5 楼
这是一个替代解决方案:$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');
自WP 4.0起,他们引入了功能
attachment_url_to_postid()
,其功能与您的find_image_post_id()
类似。请检查此网址供您参考。
#6 楼
从wordpress 4.0版开始,有一个wordpress核心功能attachment_url_to_postid,“尝试将附件URL转换为帖子ID”。但是这些函数有很大的缺陷,因为它无法转换自定义图像的url大小。尝试解决这些问题之前,几乎所有的最佳答案,但是所有这些函数都有非常繁重的数据库查询,试图获取所有现有的附件,然后遍历所有附件,以获取附件元数据并在其中找到自定义尺寸。仅当您的wordpress项目中的附件数量很少时,它才能很好地工作。但是,如果您的大型项目具有10000个以上的附件,则肯定会遇到性能问题。
但是您可以通过现有的filter_attach_url_to_postid扩展Attachment_url_to_postid核心函数,然后尝试强制自定义图像大小中的attachment_url_to_postid函数搜索。
只需将以下代码添加到活动的wordpress主题的functions.php文件中。
,然后像以前一样使用attachment_url_to_postid函数,但具有其他自定义大小功能。
add_filter( 'attachment_url_to_postid', 'change_attachment_url_to_postid', 10, 2 );
function change_attachment_url_to_postid( $post_id, $url ) {
if ( ! $post_id ) {
$file = basename( $url );
$query = array(
'post_type' => 'attachment',
'fields' => 'ids',
'meta_query' => array(
array(
'key' => '_wp_attachment_metadata',
'value' => $file,
'compare' => 'LIKE',
),
)
);
$ids = get_posts( $query );
if ( ! empty( $ids ) ) {
foreach ( $ids as $id ) {
$meta = wp_get_attachment_metadata( $id );
foreach ( $meta['sizes'] as $size => $values ) {
$image_src = wp_get_attachment_image_src( $id, $size );
if ( $values['file'] === $file && $url === array_shift( $image_src ) ) {
$post_id = $id;
}
}
}
}
}
return $post_id;
}
评论
您可以根据自己的URL设置请求变量,实例化WP_Query并从中获取信息。如果您可以更新问题并发布包含要替换的URL的HTML示例,这将很有帮助,以便我们进行讨论。
迈克就在那里。您要链接到外部站点的较大图像吗?如果不是,那么当您将图像添加到帖子中时,您只需要选择完整大小即可,并且可以选择不再将其链接到任何地方(如果不再有意义)。