类文档

FilteredIterator

💡 云策文档标注

概述

FilteredIterator 是 WordPress 中用于数组迭代的类,继承自 ArrayIterator,通过回调函数对迭代值进行过滤处理。它提供了安全机制,防止反序列化攻击。

关键要点

  • FilteredIterator 扩展 ArrayIterator,用于迭代数组或对象,并通过回调函数过滤每个值。
  • 构造函数接受可迭代数据和回调函数作为参数,使用 InputValidator::is_iterable 验证数据,否则抛出 InvalidArgument 异常。
  • 安全特性:__unserialize 和 unserialize 方法被禁用以防止反序列化攻击,__wakeup 方法在反序列化时移除回调函数。
  • current 方法在获取当前值时应用回调函数进行过滤,确保返回处理后的值。

代码示例

final class FilteredIterator extends ArrayIterator {
    private $callback;

    public function __construct($data, $callback) {
        if (InputValidator::is_iterable($data) === false) {
            throw InvalidArgument::create(1, '$data', 'iterable', gettype($data));
        }
        parent::__construct($data);
        if (is_callable($callback)) {
            $this->callback = $callback;
        }
    }

    public function current() {
        $value = parent::current();
        if (is_callable($this->callback)) {
            $value = call_user_func($this->callback, $value);
        }
        return $value;
    }
}

注意事项

  • 确保传入的数据是可迭代的,否则会抛出异常。
  • 回调函数必须是可调用的,否则不会被设置。
  • 由于安全原因,反序列化相关方法被禁用,避免潜在的安全风险。

📄 原文内容

Iterator for arrays requiring filtered values

Methods

Name Description
FilteredIterator::__construct Create a new iterator
FilteredIterator::__unserialize
FilteredIterator::__wakeup Perform reinitialization tasks.
FilteredIterator::current
FilteredIterator::unserialize

Source

final class FilteredIterator extends ArrayIterator {
	/**
	 * Callback to run as a filter
	 *
	 * @var callable
	 */
	private $callback;

	/**
	 * Create a new iterator
	 *
	 * @param array    $data     The array or object to be iterated on.
	 * @param callable $callback Callback to be called on each value
	 *
	 * @throws WpOrgRequestsExceptionInvalidArgument When the passed $data argument is not iterable.
	 */
	public function __construct($data, $callback) {
		if (InputValidator::is_iterable($data) === false) {
			throw InvalidArgument::create(1, '$data', 'iterable', gettype($data));
		}

		parent::__construct($data);

		if (is_callable($callback)) {
			$this->callback = $callback;
		}
	}

	/**
	 * Prevent unserialization of the object for security reasons.
	 *
	 * @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
	 *
	 * @param array $data Restored array of data originally serialized.
	 *
	 * @return void
	 */
	#[ReturnTypeWillChange]
	public function __unserialize($data) {}
	// phpcs:enable

	/**
	 * Perform reinitialization tasks.
	 *
	 * Prevents a callback from being injected during unserialization of an object.
	 *
	 * @return void
	 */
	public function __wakeup() {
		unset($this->callback);
	}

	/**
	 * Get the current item's value after filtering
	 *
	 * @return string
	 */
	#[ReturnTypeWillChange]
	public function current() {
		$value = parent::current();

		if (is_callable($this->callback)) {
			$value = call_user_func($this->callback, $value);
		}

		return $value;
	}

	/**
	 * Prevent creating a PHP value from a stored representation of the object for security reasons.
	 *
	 * @param string $data The serialized string.
	 *
	 * @return void
	 */
	#[ReturnTypeWillChange]
	public function unserialize($data) {}
}