0

我必须在 Wordpress 中将文件名更改为图像/文件名和文件/文件名,最后我使用了 WP-CLI 的搜索替换功能。

这是我执行的shell命令:

wp search-replace '(")(5\.jpg)' 'images/${2}' wp_postmeta --regex --regex-delimiter='/' --dry-run --skip-columns=meta_key --debug=true

这给了我回信息:0 replacements to be made

这是数据库中的一个条目:

a:5:{s:5:"width";i:2048;s:6:"height";i:1536;s:4:"file";s:5:"5.jpg";s:5:"sizes";a:4:{s:9:"thumbnail";a:4:{s:4:"file";s:13:"5-150x150.jpg";s:5:"width";i:150;s:6:"height";i:150;s:9:"mime-type";s:10:"image/jpeg";}s:6:"medium";a:4:{s:4:"file";s:13:"5-300x225.jpg";s:5:"width";i:300;s:6:"height";i:225;s:9:"mime-type";s:10:"image/jpeg";}s:12:"medium_large";a:4:{s:4:"file";s:13:"5-768x576.jpg";s:5:"width";i:768;s:6:"height";i:576;s:9:"mime-type";s:10:"image/jpeg";}s:5:"large";a:4:{s:4:"file";s:14:"5-1024x768.jpg";s:5:"width";i:1024;s:6:"height";i:768;s:9:"mime-type";s:10:"image/jpeg";}}s:10:"image_meta";a:12:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:0:"";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";s:11:"orientation";s:1:"0";s:8:"keywords";a:0:{}}}

我创建了一个自定义 PHP 脚本,如下所示:

$data = 'a:5:{s:5:"width";i:2048;s:6:"height";i:1536;s:4:"file";s:5:"5.jpg";s:5:"sizes";a:4:{s:9:"thumbnail";a:4:{s:4:"file";s:13:"5-150x150.jpg";s:5:"width";i:150;s:6:"height";i:150;s:9:"mime-type";s:10:"image/jpeg";}s:6:"medium";a:4:{s:4:"file";s:13:"5-300x225.jpg";s:5:"width";i:300;s:6:"height";i:225;s:9:"mime-type";s:10:"image/jpeg";}s:12:"medium_large";a:4:{s:4:"file";s:13:"5-768x576.jpg";s:5:"width";i:768;s:6:"height";i:576;s:9:"mime-type";s:10:"image/jpeg";}s:5:"large";a:4:{s:4:"file";s:14:"5-1024x768.jpg";s:5:"width";i:1024;s:6:"height";i:768;s:9:"mime-type";s:10:"image/jpeg";}}s:10:"image_meta";a:12:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:0:"";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";s:11:"orientation";s:1:"0";s:8:"keywords";a:0:{}}}';

if (preg_match('/(")(5\.jpg)/', $data)) {
    echo "A match was found.";
} else {
    echo "A match was not found.";
}
echo '<br>';

$data = preg_replace( '/(")(5\.jpg)/', 'images/${2}', $data );
var_dump($data);

这可以很好地替换数据,我得到的结果为 a:5:{s:5:"width";i:2048;s:6:"height";i:1536;s:4:"file";s:5:"images/5.jpg" ...

这是 WP-CLI search-replace 的源代码

<?php
namespace WP_CLI;
class SearchReplacer {
    private $from, $to;
    private $recurse_objects;
    private $regex;
    private $regex_flags;
    private $regex_delimiter;
    private $logging;
    private $log_data;
    private $max_recursion;
    /**
     * @param string  $from            String we're looking to replace.
     * @param string  $to              What we want it to be replaced with.
     * @param bool    $recurse_objects Should objects be recursively replaced?
     * @param bool    $regex           Whether `$from` is a regular expression.
     * @param string  $regex_flags     Flags for regular expression.
     * @param string  $regex_delimiter Delimiter for regular expression.
     * @param bool    $logging         Whether logging.
     */
    function __construct( $from, $to, $recurse_objects = false, $regex = false, $regex_flags = '', $regex_delimiter = '/', $logging = false ) {
        $this->from = $from;
        $this->to = $to;
        $this->recurse_objects = $recurse_objects;
        $this->regex = $regex;
        $this->regex_flags = $regex_flags;
        $this->regex_delimiter = $regex_delimiter;
        $this->logging = $logging;
        $this->clear_log_data();
        // Get the XDebug nesting level. Will be zero (no limit) if no value is set
        $this->max_recursion = intval( ini_get( 'xdebug.max_nesting_level' ) );
    }
    /**
     * Take a serialised array and unserialise it replacing elements as needed and
     * unserialising any subordinate arrays and performing the replace on those too.
     * Ignores any serialized objects unless $recurse_objects is set to true.
     *
     * @param array|string $data            The data to operate on.
     * @param bool         $serialised      Does the value of $data need to be unserialized?
     *
     * @return array       The original array with all elements replaced as needed.
     */
    function run( $data, $serialised = false ) {
        return $this->_run( $data, $serialised );
    }
    /**
     * @param int          $recursion_level Current recursion depth within the original data.
     * @param array        $visited_data    Data that has been seen in previous recursion iterations.
     */
    private function _run( $data, $serialised, $recursion_level = 0, $visited_data = array() ) {
        // some unseriliased data cannot be re-serialised eg. SimpleXMLElements
        try {
            if ( $this->recurse_objects ) {
                // If we've reached the maximum recursion level, short circuit
                if ( $this->max_recursion != 0 && $recursion_level >= $this->max_recursion ) {
                    return $data;
                }
                if ( is_array( $data ) || is_object( $data ) ) {
                    // If we've seen this exact object or array before, short circuit
                    if ( in_array( $data, $visited_data, true ) ) {
                        return $data; // Avoid infinite loops when there's a cycle
                    }
                    // Add this data to the list of
                    $visited_data[] = $data;
                }
            }
            if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
                $data = $this->_run( $unserialized, true, $recursion_level + 1 );
            }
            elseif ( is_array( $data ) ) {
                $keys = array_keys( $data );
                foreach ( $keys as $key ) {
                    $data[ $key ]= $this->_run( $data[$key], false, $recursion_level + 1, $visited_data );
                }
            }
            elseif ( $this->recurse_objects && is_object( $data ) ) {
                foreach ( $data as $key => $value ) {
                    $data->$key = $this->_run( $value, false, $recursion_level + 1, $visited_data );
                }
            }
            else if ( is_string( $data ) ) {
                if ( $this->logging ) {
                    $old_data = $data;
                }
                if ( $this->regex ) {
                    $search_regex = $this->regex_delimiter;
                    $search_regex .= $this->from;
                    $search_regex .= $this->regex_delimiter;
                    $search_regex .= $this->regex_flags;
                    $data = preg_replace( $search_regex, $this->to, $data );
                } else {
                    $data = str_replace( $this->from, $this->to, $data );
                }
                if ( $this->logging && $old_data !== $data ) {
                    $this->log_data[] = $old_data;
                }
            }
            if ( $serialised )
                return serialize( $data );
        } catch( Exception $error ) {
        }
        return $data;
    }
    /**
     * Gets existing data saved for this run when logging.
     * @return array Array of data strings, prior to replacements.
     */
    public function get_log_data() {
        return $this->log_data;
    }
    /**
     * Clears data stored for logging.
     */
    public function clear_log_data() {
        $this->log_data = array();
    }
}

我使用的和这里使用的完全相同preg_replace

$data = preg_replace( $search_regex, $this->to, $data );

为什么这在 WP-CLI 中不起作用?

4

0 回答 0