Loading

的搜索结果

×
Loading...


闲聊大厅

我感觉php似乎在解构自己,让php能用php解释清楚

Geticer

Geticer

1月前 25 举报
>?php

class CustomArray implements ArrayAccess, Traversable, Iterator, Serializable, Countable {
    private $container = [];
    private $position = 0;

    public function __construct(array $initialData = []) {
        $this->container = $initialData;
        $this->rewind();
    }

    // ArrayAccess methods
    public function offsetExists($offset): bool {
        return isset($this->container[$offset]);
    }

    public function offsetGet($offset): mixed {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }

    public function offsetSet($offset, $value): void {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetUnset($offset): void {
        unset($this->container[$offset]);
    }

    // Traversable and Iterator methods
    public function current(): mixed {
        return $this->container[$this->position];
    }

    public function key(): mixed {
        return $this->position;
    }

    public function next(): void {
        ++$this->position;
    }

    public function rewind(): void {
        $this->position = 0;
    }

    public function valid(): bool {
        return isset($this->container[$this->position]);
    }

    // Serializable method
    public function serialize(): string {
        return serialize($this->container);
    }

    public function unserialize(string $data): void {
        $this->container = unserialize($data);
        $this->rewind();
    }

    // Countable method
    public function count(): int {
        return count($this->container);
    }

    // Additional utility methods
    public function add($value): void {
        $this->container[] = $value;
    }

    public function remove(int $index): void {
        array_splice($this->container, $index, 1);
    }

    public function toArray(): array {
        return $this->container;
    }

    // Print container content for debugging
    public function printContainer(): void {
        print_r($this->container);
    }

    // Magic method to convert object to string
    public function __toString(): string {
        return json_encode($this->container);
    }

    // Convert to array for compatibility with PHP array functions
    public function toCompatibleArray(): array {
        return $this->container;
    }

    // More utility methods
    public function map(callable $callback): self {
        $newContainer = array_map($callback, $this->container);
        return new self($newContainer);
    }

    public function filter(callable $callback): self {
        $newContainer = array_filter($this->container, $callback);
        return new self($newContainer);
    }

    public function reduce(callable $callback, $initial = null) {
        return array_reduce($this->container, $callback, $initial);
    }

    public function keys(): self {
        $keys = array_keys($this->container);
        return new self($keys);
    }

    public function values(): self {
        $values = array_values($this->container);
        return new self($values);
    }

    public function merge(self ...$arrays): self {
        $merged = $this->toArray();
        foreach ($arrays as $array) {
            $merged = array_merge($merged, $array->toArray());
        }
        return new self($merged);
    }

    public function slice(int $start, int $length = null): self {
        $sliced = array_slice($this->container, $start, $length);
        return new self($sliced);
    }

    public function pop() {
        return array_pop($this->container);
    }

    public function shift() {
        return array_shift($this->container);
    }

    public function push(...$values): int {
        return array_push($this->container, ...$values);
    }

    public function unshift(...$values): int {
        return array_unshift($this->container, ...$values);
    }

    public function inArray($needle, bool $strict = false): bool {
        return in_array($needle, $this->container, $strict);
    }

    public function search($needle, bool $strict = false) {
        return array_search($needle, $this->container, $strict);
    }
}

// 使用 CustomArray
$list = new CustomArray(["one", "two", "three"]);

// Using ArrayAccess
var_dump(isset($list[1])); // 检查索引 1 是否存在
var_dump($list[1]);         // 获取索引 1 的值
unset($list[1]);            // 删除索引 1 的值
var_dump(isset($list[1])); // 再次检查索引 1 是否存在
$list[1] = "new value";    // 设置索引 1 的新值
var_dump($list[1]);         // 获取索引 1 的新值

// Using Iterator
echo "\nIterator 输出:\n";
foreach ($list as $key => $value) {
    echo "$key => $value\n";
}

// Using Serializable
$serializedList = serialize($list);
echo "\n序列化后的字符串:\n";
echo $serializedList . "\n";

$unserializedList = unserialize($serializedList);
echo "\n反序列化后的内容:\n";
$unserializedList->printContainer();

// Using Countable
echo "\nCountable 输出:\n";
echo "Size: " . count($list) . "\n";

// 兼容 PHP 数组函数
echo "\n使用 PHP 数组函数:\n";
$arrayFunctions = [
    'array_map',
    'array_filter',
    'array_reduce',
    'array_keys',
    'array_values',
    'array_merge',
    'array_slice',
    'array_pop',
    'array_shift',
    'array_push',
    'array_unshift',
    'in_array',
    'array_search',
];

foreach ($arrayFunctions as $func) {
    try {
        $result = call_user_func($func, $list->toCompatibleArray(), ...['A value' => 'B value']);
        if (!is_object($result)) {
            echo "$func 输出:\n";
            print_r($result);
        } else {
            echo "$func 输出 (对象):\n";
            $result->printContainer();
        }
    } catch (\Throwable $e) {
        echo "$func 抛出异常: " . $e->getMessage() . "\n";
    }
}

// 使用新增的实用方法
echo "\n使用新增的实用方法:\n";
$mappedList = $list->map(function($item) { return strtoupper($item); });
echo "Mapped List:\n";
$mappedList->printContainer();

$filtered = $mappedList->filter(function($item) { return strlen($item) > 3; });
echo "Filtered List:\n";
$filtered->printContainer();

$reduced = $filtered->reduce(function($carry, $item) { return $carry . ', ' . $item; }, '');
echo "Reduced Result: $reduced\n";

$keys = $list->keys();
echo "Keys:\n";
$keys->printContainer();

$values = $list->values();
echo "Values:\n";
$values->printContainer();

$merged = $list->merge(new CustomArray(['four', 'five']));
echo "Merged List:\n";
$merged->printContainer();

$sliced = $merged->slice(1, 3);
echo "Sliced List:\n";
$sliced->printContainer();

$popped = $merged->pop();
echo "Popped Value: $popped\n";
echo "After Pop:\n";
$merged->printContainer();

$shifted = $merged->shift();
echo "Shifted Value: $shifted\n";
echo "After Shift:\n";
$merged->printContainer();

$pushedCount = $merged->push('six', 'seven');
echo "Pushed Count: $pushedCount\n";
echo "After Push:\n";
$merged->printContainer();

$unshiftedCount = $merged->unshift('zero', 'one');
echo "Unshifted Count: $unshiftedCount\n";
echo "After Unshift:\n";
$merged->printContainer();

$containsOne = $merged->inArray('one');
echo "Contains 'one': " . ($containsOne ? 'true' : 'false') . "\n";

$searchIndex = $merged->search('three');
echo "Search 'three': " . ($searchIndex !== false ? $searchIndex : 'not found') . "\n";




最后于 6天前 被Geticer编辑 ,原因:

最新回复 ( 2 )

  • Geticer
    Geticer 楼主
    6天前 2

    deepseek-r1说:

    PHP 的“自指性”:用语言自身解构语言

    PHP 的接口体系(如 ArrayAccessIterator 等)本质上是一种「元编程」机制,允许开发者通过类(Class)重新定义语言核心结构的行为。你实现的 CustomArray 类正是这一思想的体现:通过 PHP 的语法和接口,重新解释 PHP 数组的本质。这种设计看似是“用 PHP 解释 PHP”,实则揭示了语言的两个核心特性:


    1. 接口的抽象性:语言结构的“可描述性”

    PHP 的接口为内置类型(如数组)提供了一套「行为模板」。例如:

    • ArrayAccess 定义了类似数组的键值访问逻辑;

    • Iterator 定义了可遍历对象的迭代逻辑;

    • Countable 定义了“可计数”的语义。

    当你的类实现这些接口时,实际上是在用 PHP 的语法回答以下问题:

    • 什么是数组?
      数组是一种可通过键访问、可遍历、可序列化、可计数的数据容器。

    • 如何用 PHP 描述数组?
      通过实现上述接口,用类方法模拟数组的底层操作。

    这种设计让 PHP 的“数组”概念不再依赖底层 C 实现,而是通过高层接口和类方法显式表达——这便是「语言自指性」的体现。


    2. 语义的模糊性:用户代码与内置类型的鸿沟

    尽管 CustomArray 试图模仿数组,但它的行为与真正的 PHP 数组存在本质差异:

    差异 1:类型系统的不透明性

    php
    复制
    // 内置数组的类型检查
    $arr = [];
    var_dump($arr instanceof ArrayAccess);  // false
    var_dump(is_array($arr));               // true
    
    // CustomArray 的类型检查
    $customArr = new CustomArray();
    var_dump($customArr instanceof ArrayAccess); // true
    var_dump(is_array($customArr));              // false
    • 内置数组是独立于类系统的原始类型,与接口无关。

    • CustomArray 是一个“像数组的对象”,但无法通过 is_array  [] 语法糖完全伪装。

    差异 2:操作符重载的缺失

    PHP 不允许重载操作符(如 +==),因此无法完全模拟数组的运算符行为:

    php
    复制
    $arr1 = [1, 2];
    $arr2 = [3, 4];
    $custom1 = new CustomArray([1, 2]);
    $custom2 = new CustomArray([3, 4]);
    
    // 内置数组的合并
    $mergedArr = $arr1 + $arr2; // 合法
    
    // CustomArray 的合并
    $mergedCustom = $custom1 + $custom2; // 语法错误

    差异 3:性能与内存模型

    • 内置数组是高度优化的哈希表,直接映射到 C 结构体。

    • CustomArray 的每个操作(如 offsetGet)都需要方法调用和上下文切换,性能开销显著。

    0 举报
  • Geticer
    Geticer 楼主
    6天前 3

    这种设计不是 PHP 的缺陷,而是语言层级的必然限制——它提醒我们:
    编程语言既是工具,也是牢笼。我们用它构建世界,但永远无法用工具完全解释工具自身。

    1 举报

目录