абстрактные классы и статические методы

KOLANICH

Новичок
Fatal error: Cannot call abstract method FileTreeWalker::filefunc() in *********
PHP:
abstract class FileTreeWalker{
	abstract static function dirfunc($cfile,$dir);
	abstract static function filefunc($cfile,$dir);
	static function walk($dir){
		$file = scandir($dir);
		$files = $dirs = array();
		for($i=2;$cfile=$file[$i];$i++) {
			if(is_dir("{$dir}/{$cfile}") ){
				$dirs[]=self::dirfunc($cfile,$dir);
			}else $files[]=self::filefunc($cfile,$dir);//Fatal error: Cannot call abstract method FileTreeWalker::filefunc() in ********* ну и так далее
		}
		$file = array_merge($dirs, $files);
	}
};
class FileTreeBuilder extends FileTreeWalker{
	static function dirfunc($cfile,$dir){
		return new FileTreeDir($cfile,$dir);
	}
	static function filefunc($cfile,$dir){
		return new FileTreeItem($cfile,$dir);
	}
	
};
как пофиксить
 

KOLANICH

Новичок
я не знаю, какие у него классы-потомки
я хочу вынести общий функционал в родитель, причём в создании экземпляра нужды нет
 

Sufir

Я не волшебник, я только учусь
Вы сами же и ответили на свой вопрос "как пофиксить" - "вынести общий функционал в родитель". Сделайте метод не абстрактным и реализуйте необходимый функционал.
 

KOLANICH

Новичок
дело в том, что хранить в объекте ничего не нужно, следовательно, создавать объект не нужно
замыкания и трейты использовать не могу из-за низкой версии php на хостинге
 

AmdY

Пью пиво
Команда форума
KOLANICH
сделай методо не статическим и вызывай в той строчке $this->filefunc()
 

KOLANICH

Новичок
это вариант решениия проблемы, но
создавать объект не нужно
первоначально написал с замыканиями, но обнаружив, что они не поддерживаются, решил написать с классами
 

Sufir

Я не волшебник, я только учусь
Ммм... Похоже я не понял в чём проблема. Почему бы не сделать вот так?
PHP:
abstract class FileTreeWalker {
    
    static function filefunc( $cfile, $dir ){
        
        echo $cfile, ' ', $dir, '...';
        
    }


    static function walk( $dir ){
        
        $cfile = 'Do';
        
        self::filefunc( $cfile, $dir );
        
    }
    
};

class FileTreeBuilder extends FileTreeWalker {

    // Выносим в родитель
    /*static function filefunc($cfile,$dir){
        return new FileTreeItem($cfile,$dir);
    }*/
    
};

FileTreeBuilder::walk( 'something' );  //  Do something...
 

Sufir

Я не волшебник, я только учусь
А, имеется в виду наверное, что из родителя должна вызываться дочерняя filefunc?.. Смутило заявление "хочу вынести общий функционал в родитель"...
А почему нельзя создавать объект?
 

KOLANICH

Новичок
память жрать будет, а также совершать лишнюю работу, то есть для каждой папки придётся создавать свой walker, причём абсолютно необоснованно

вобще, ипойду пересмотрю алгоритм, видимо он неверный
 

Sufir

Я не волшебник, я только учусь
Ну можно вот так:
PHP:
interface FileTreeWalkerInterface{
    
    public static function filefunc( $cfile, $dir );
    
}

abstract class FileTreeWalker {
    
    static function walk( $dir ){
        
        $cfile = 'Do';
        
        call_user_func( array( get_called_class(), 'filefunc' ), $cfile, $dir );
        
    }
    
};

class FileTreeBuilder extends FileTreeWalker implements FileTreeWalkerInterface {
    
    static function filefunc( $cfile, $dir ){
        
        echo $cfile, ' ', $dir, '...';
        
    }
    
};

FileTreeBuilder::walk( 'something' );  //  Do something...
Но работать будет только в 5.3+ скорее всего.
 

Sufir

Я не волшебник, я только учусь
Но вообще, от такого хостинга лучше б отказаться. Какой смысл писать новый проект под 5.2, который уж скоро год, как объявлен не поддерживаемым?.. Ну, да ситуация у всех своя.
 
Сверху