我已经习惯了Java HashSets,ArrayLists以及其他Collections.但我现在正在开发一个PHP项目.
我需要创建一个集合,用对象填充该集合(在本例中为字符串),但集合只能包含每个对象一次.另外我想从这个集合中删除某个对象(如果存在).使用Java集合类可以很容易.但是我如何在PHP中实现它呢?
有什么方法可以解决array()这个问题吗?我正在使用PHP 5.3.
到目前为止,我已经使用了程序独立的自动加载器函数,并使用spl_autoload_register()注册它们以自动加载我的(通常)命名空间类.最近,我注意到人们提到将自动加载器类与一些着名的PHP框架结合使用.
我的代码几乎所有代码都是面向对象的,但在这个实例中,我并没有看到在基本函数中使用类"Autoloader"的优势.在可测试性方面,我觉得在我的测试中使用class_exists()检查来验证过程函数是否正确加载文件.
所以我的问题是三个:
UPDATE
下面是我可能使用的典型自动加载功能的一些示例代码.它是元代码,所以不要寻找错别字.我组织我的目录结构,以便它们镜像命名空间.从explode_namespaces()理论上讲,假设函数可以作为静态方法与autoload()类中的静态方法一起包含在内,这是一个好处.将这些不同的"实用程序"函数组合为单个类中的方法可能更清晰.
function autoload($class_name)
{
  $root = APP_LIBS; // a directory path constant set at config time
  if ($namespaces = explode_namespaces($class_name)) {
    $domain = array_shift($namespaces);
    $root  .= "/$domain/";
    $class_name = array_pop($namespaces);
    $directories = array();
    foreach ($namespaces as $directory) {
      $directories[] = $directory;
    }
    $root .= implode($directories, '/');
  }
  $file = "$root/$class_name.php";
  if (file_exists($file)) {
    include $file;
  }
}
Run Code Online (Sandbox Code Playgroud) 使用fopen与SplFileObjectPHP 相反的优缺点是什么?
从我看到的,SplFileObject在适用的情况下抛出异常,这使得在使用try...catch错误处理时更方便.除此之外,还有其他理由推荐一个吗?
(额外奖励:它为什么被称为SplFileObject?代表什么Spl?为什么不简单FileObject?)
更新:它的一个限制SplFileObject是它(还)没有close成员函数.在某些情况下,这可能是一个问题(例如:Unlink和SplFileObject).
我写了一个简单的集合类,以便我可以将我的数组存储在对象中:
class App_Collection implements ArrayAccess, IteratorAggregate, Countable
{
    public $data = array();
    public function count()
    {
        return count($this->data);
    }
    public function offsetExists($offset)
    {         
        return (isset($this->data[$offset]));
    }   
    public function offsetGet($offset)
    {  
        if ($this->offsetExists($offset))
        {
            return $this->data[$offset];
        }
        return false;
    }
    public function offsetSet($offset, $value)
    {         
        if ($offset)
        {
            $this->data[$offset] = $value;
        }  
        else
        {
            $this->data[] = $value; 
        }
    }
    public function offsetUnset($offset)
    {
        unset($this->data[$offset]);
    }
    public function getIterator()
    {
        return new ArrayIterator($this->data);
    }
}
Run Code Online (Sandbox Code Playgroud)
问题:在此对象上调用array_key_exists()时,它总是返回"false",因为SPL似乎没有处理此函数.有没有办法解决?
概念证明:
$collection = new App_Collection(); …Run Code Online (Sandbox Code Playgroud) 我正在使用RecursiveDirectoryIterator并RecursiveIteratorIterator使用如下代码构建文件列表树.我需要对列表进行排序 - 按字母顺序排列目录,或按字母顺序排列.
谁能告诉我如何对文件列表进行排序?
$dir_iterator = new RecursiveDirectoryIterator($groupDirectory);
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $file) {
    // do stuff with $file
}
Run Code Online (Sandbox Code Playgroud) PHP文档不是很明确,只说明:
SplObjectStorage :: offsetExists 检查存储中是否存在对象.(PHP> = 5.3.0)
SplObjectStorage :: contains 检查存储是否包含提供的对象.(PHP> = 5.1.0)
这对我来说几乎是一回事.
问题:除了offsetExists仅在5.3.0中可用之外,2之间有什么区别?
我进行的小测试......
$s = new SplObjectStorage();
$o1 = new StdClass();
$o2 = new StdClass();
$o3 = "I'm not an object!";
$s->attach($o1);
var_dump($s->contains($o1));
var_dump($s->offsetExists($o1));
echo '<br>';
var_dump($s->contains($o2));
var_dump($s->offsetExists($o2));
echo '<br>';
var_dump($s->contains($o3));
var_dump($s->offsetExists($o3));
Run Code Online (Sandbox Code Playgroud)
输出:
boolean true
boolean true
boolean false
boolean false
Warning: SplObjectStorage::contains() expects parameter 1 to be object, string given in index.php on line 15
null
Warning: SplObjectStorage::offsetExists() expects parameter 1 to be …Run Code Online (Sandbox Code Playgroud) 我有这样一个数组:
$arr = array(
        $foo = array(
            'donuts' => array(
                    'name' => 'lionel ritchie',
                    'animal' => 'manatee',
                )
        )
    );
Run Code Online (Sandbox Code Playgroud)
使用'SPL Recursive Iterator'的魔力和这段代码:
$bar = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
    foreach($bar as $key => $value) 
    {
        echo $key . ": " . $value . "<br>";
    }
Run Code Online (Sandbox Code Playgroud)
我可以遍历多维数组并返回key =>值对,例如:
名称:lionel ritchie动物:海牛
但是,我还需要返回当前迭代数组的PARENT元素,所以...
甜甜圈名称:lionel richie 甜甜圈动物:海牛
这可能吗?
(我只是意识到所有'Recursive Iterator'的东西,所以如果我遗漏了一些明显的东西,我道歉.)
我已经开始从ArrayIterators学习PHP SPL了,我想知道使用SPL ArrayObject,ArrayIterator,RecursiveArrayIterator而不是常规数组有什么好处?
a)我听说使用SPL迭代器的循环会减少内存使用量(但为什么?).我真的不知道相信这个或不相信,因为我不明白它如何减少内存使用量.
b)谈到RecursiveArrayIterator我们可以说有时它可以保存一些代码行(我们使用一个foreach构造而不是2+(取决于数组维度)).
可能我的问题对某些人来说似乎很容易,但关于SPL的信息/文档太少.
谢谢
我正在测试SplFixedArray构建一个星期几的数组,我得到以下结果:
<?php
$days = new SplFixedArray(7);
$days[0] = "Monday";
$days[1] = "Tuesday";
$days[2] = "Wednesday";
$days[3] = "Thursday";
$days[4] = "Friday";
$days[5] = "Saturday";
$days[6] = "Sunday";
echo memory_get_peak_usage() . "\n"; //Returns 327688
echo memory_get_usage() . "\n"; //Returns 327140
echo memory_get_peak_usage(true) . "\n"; //Returns 524288
echo memory_get_usage(true) . "\n"; //Returns 524288 
Run Code Online (Sandbox Code Playgroud)
使用传统阵列:
<?php
$days = array();
$days[0] = "Monday";
$days[1] = "Tuesday";
$days[2] = "Wednesday";
$days[3] = "Thursday";
$days[4] = "Friday";
$days[5] = "Saturday";
$days[6] = "Sunday";
echo memory_get_peak_usage() . …Run Code Online (Sandbox Code Playgroud) 我正在访问SPLFileInfo对象中的许多文件.我看到了获取文件的路径,文件名甚至扩展名的方法.有没有办法获得没有扩展名的文件名?这是我一直在使用的代码,但我希望能得到更优雅的东西.有开箱即用的解决方案吗?
$file = new SplFileInfo("path/to/file.txt.zip"); 
echo 'basename: '.$file->getBasename();  
echo PHP_EOL;
echo 'filename: '.$file->getFilename();
echo PHP_EOL;    
echo 'extension: '.$file->getExtension();
echo PHP_EOL;    
echo 'basename w/o extension: '.$file->getBasename('.'.$file->getExtension());
>>OUTPUT
>>basename: file.txt.zip
>>filename: file.txt.zip
>>extension: zip
>>basename w/o extension: file.txt
Run Code Online (Sandbox Code Playgroud)