Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Классы и переменные в переменных, совместить возможно?! 
V
    Опции темы
Deja_Vu
Дата 9.7.2007, 01:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 15.6.2007
Где: Казань

Репутация: нет
Всего: 2



Код

$a = "b";
$$a = 1;
$c = 1;
if $c == $b print "ok";

Очень удобно....
Хотелось бы в  классе использовать этот механизм. Т
акое возможно ... и если да, то как?!
ниже мой пример ...  классом.

Код

class TXMLParser
{     
    // Сам парсер
    var $xmlparser;         
    
    // Информация о текущем теге
    var $currebtTag;
    // Извлекаемые данные
    var $FILE;
    var $MODNAME;
    var $VERSION;
    var $AUTHOR;
    var $DESCRIPTION;

    
    function TXMLParser()
    {
        $this->FILE = "";
        $this->MODNAME = "";
        $this->VERSION = "";
        $this->AUTHOR = "";
        $this->DESCRIPTION = "";  
        $this->currentTag = "FILE";
        
        $this->xmlparser = xml_parser_create();    
        
        xml_set_object($this->xmlparser, &$this);
        xml_set_element_handler($this->xmlparser, Array(&$this, "startTagEdit"), Array(&$this, "endTagEdit"));
        xml_set_character_data_handler($this->xmlparser,  Array(&$this, "dataEdit"));
    }                                                        
    
    function startTagEdit($parser, $tagname)
    {
        /* DEBUG */
        #print ("<br> \t"."&lt;".$tagname.">"."\r\n");
        /* DEBUG */
        
        // Узнаю что за информация о моде
        $this->currentTag =  $tagname;
    }

    function endTagEdit($parser, $tagname)    {}
    
    function dataEdit($parser, $data)
    {                                     
        
        /* Записываю информацию в поле
        которое указано в currentTag */
        if ($currentTag != "MOD") {$this->$currentTag = $data;} #Вот тута хочу пременить этот механизм!
    }



PM Skype   Вверх
sTa1kEr
Дата 9.7.2007, 01:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Если я вас правильно понял, то в 49ой строке вам нужно написать
Код

$this->{$this->currentTag} = $data;

Т.е. значение переменной в фигурных скобках является переменным именем поля. Для примера, можно написать так 
Код

$this->{"DESCRIPTION"} = $data;

И это будет полностью эквивалентно
Код

$this->DESCRIPTION = $data;


Добавлено через 5 минут и 9 секунд
В вашем примере PHP будет интерпретировать 49-ую строку, как имя поля локальной переменной $currentTag. Но у вас не опредлена локальная переменная $currentTag и поэтому PHP скажет, что ткого поля не сществует.
PM MAIL   Вверх
Deja_Vu
Дата 9.7.2007, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 15.6.2007
Где: Казань

Репутация: нет
Всего: 2



Спасибо - это оно.
PM Skype   Вверх
WIPS
Дата 9.7.2007, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 22.5.2006
Где: Украина, Киев

Репутация: 1
Всего: 8



sTa1kEr, спасибо за:
Код

$this->{$this->currentTag} = $data;
 
Мне как раз надо было сделать кое-что похожее.
--------------------
Автопроизводители, машины, марки, модели!
PM MAIL WWW ICQ Skype   Вверх
Deja_Vu
Дата 9.7.2007, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 15.6.2007
Где: Казань

Репутация: нет
Всего: 2



Появилась очередая проблемка с этим куском -((
У меня дома этот код работает.

Код
    
class TXMLParser
{     
    // Сам парсер
    var $xmlparser;         
    
    // Информация о текущем теге
    var $currebtTag;
    // Извлекаемые данные
    var $FILE;
    var $MODNAME;
    var $VERSION;
    var $AUTHOR;
    var $DESCRIPTION;
    var $TMP;

function dataEdit($parser, $data)
    {                                     
        /* DEBUG */
        print ("<br> \t".$data."\r\n");
        /* DEBUG */

        /* Записываю информацию в поле
        которое указано в currentTag */
        if ($this->currentTag != "MOD")
        {
            $this->{$this->currentTag} = $data; // {"File"} = &(&currentTag = "File)
            /* DEBUG */
            if ($this->currentTag != "TMP") { print ("<br> \t"."\$this->currentTag : ".$this->currentTag."\r\n"); }
            /* DEBUG */
        }

    }
}

и проверка выводит результаты:
Код
    /* DEBUG */
    print ("<br> <b>=\$ModInfo=</b>");
    print ("<br> -\$ModInfo->TMP :: ".$ModInfo->TMP."\r\n");
    print ("<br> -\$ModInfo->FILE :: ".$ModInfo->FILE."\r\n");
    print ("<br> -\$ModInfo->MODNAME :: ".$ModInfo->MODNAME."\r\n");
    print ("<br> -\$ModInfo->VERSION :: ".$ModInfo->VERSION."\r\n");
    print ("<br> -\$ModInfo->AUTHOR :: ".$ModInfo->AUTHOR."\r\n");
    print ("<br> -\$ModInfo->DESCRIPTION :: ".$ModInfo->DESCRIPTION."\r\n");
    print ("<br><b><hr></b>\r\n");
    /* DEBUG */        


На сервере же ... после цикличного обхода 1 куска ... проверка показывает пустой результат...
Вот: http://aanda.fatal.ru/sserver.php
В проверочном куске выводятся те параметры которые были найдены в файле и помещены в $this->currentTag, который используется затем как параметр - а вот потом, как я понимаю

Код
$this->{$this->currentTag} = $data;

не срабатывает.

Как с этим справится?!
Не хочу использоваться switch.


Это сообщение отредактировал(а) Deja_Vu - 9.7.2007, 15:12
PM Skype   Вверх
sTa1kEr
Дата 9.7.2007, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Deja_Vu, на сервере PHP 4? Давно пора уже переходить на PHP 5 smile А для 4ого PHP можно попробовать сначала записать значение в локальную переменную
Код

        if ($this->currentTag != "MOD")
        {
            $currentTag = $this->currentTag;
            $this->$currentTag = $data; // {"File"} = &(&currentTag = "File)
            /* DEBUG */
            if ($this->currentTag != "TMP") { print ("<br> \t"."\$this->currentTag : ".$this->currentTag."\r\n"); }
            /* DEBUG */
        }

По идеи только так, хотя проверить не могу - нету PHP 4.
PM MAIL   Вверх
Deja_Vu
Дата 9.7.2007, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 15.6.2007
Где: Казань

Репутация: нет
Всего: 2



Цитата(sTa1kEr @ 9.7.2007,  17:36)
Deja_Vu, на сервере PHP 4? Давно пора уже переходить на PHP 5 smile А для 4ого PHP можно попробовать сначала записать значение в локальную переменную
Код

        if ($this->currentTag != "MOD")
        {
            $currentTag = $this->currentTag;
            $this->$currentTag = $data; // {"File"} = &(&currentTag = "File)
            /* DEBUG */
            if ($this->currentTag != "TMP") { print ("<br> \t"."\$this->currentTag : ".$this->currentTag."\r\n"); }
            /* DEBUG */
        }

По идеи только так, хотя проверить не могу - нету PHP 4.

хз какой PHP ... не мой же сервак.
Но так тоже не прошло.
ну да ладно ... это тестовый сервак.


Хотя счас через 4 php дома прогоню
PM Skype   Вверх
Deja_Vu
Дата 10.7.2007, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 15.6.2007
Где: Казань

Репутация: нет
Всего: 2



del

Это сообщение отредактировал(а) Deja_Vu - 10.7.2007, 21:56
PM Skype   Вверх
sTa1kEr
Дата 10.7.2007, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Могу еще предложить такой вариант:
Код

class TXMLParser
{     
    var $_data = array();
    // Сам парсер
    var $xmlparser;         
    
    // Информация о текущем теге
    var $currebtTag;
    // Извлекаемые данные
    var $FILE;
    var $MODNAME;
    var $VERSION;
    var $AUTHOR;
    var $DESCRIPTION;
    var $TMP;

    function TXMLParser()
    {
        $this->FILE =& $this->_data["FILE"];
        $this->MODNAME =& $this->_data["MODNAME"];
        $this->VERSION =& $this->_data["VERSION"];
        $this->AUTHOR =& $this->_data["AUTHOR"];
        $this->DESCRIPTION =& $this->_data["DESCRIPTION"];
        $this->TMP =& $this->_data["TMP"];
    }

    function dataEdit($parser, $data)
    {                                     
        /* DEBUG */
        print ("<br> \t".$data."\r\n");
        /* DEBUG */
        /* Записываю информацию в поле
        которое указано в currentTag */
        if ($this->currentTag != "MOD")
        {
            $this->_data[$this->currentTag] = $data; // {"File"} = &(&currentTag = "File)
            /* DEBUG */
            if ($this->currentTag != "TMP") { print ("<br> \t"."\$this->currentTag : ".$this->currentTag."\r\n"); }
            /* DEBUG */
        }
    }
}


Хотя тогда уж проще просто в массиве данные хранить...
PM MAIL   Вверх
Deja_Vu
Дата 10.7.2007, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 15.6.2007
Где: Казань

Репутация: нет
Всего: 2



Проблема!!!
Оказывается PHP 4

Код
$this->{$this->currentTag} = $data;

верно интерпретирует.
Проблема в другом.
После изменения атрибутов класса внутри парсящих XML функций, 
все аттрибуты класса на выходе из них оказываются не изменны!!!
Код
<?php /* Created on: 03.07.2007 */ 
/*
На данный момент скрипт делает 
список файлов в папках.
*/         
 
$windows = false;
if ($windows) 
{
    $razdel = "\\";     
}
 else
{
    $razdel = "/";     
}

$root_folder = "base".$razdel; 

class TXMLParser
{     
    // Сам парсер
    var $xmlparser;         
    
    // Информация о текущем теге
    var $currentTag;
    // Извлекаемые данные
    var $FILE;
    var $MODNAME;
    var $VERSION;
    var $AUTHOR;
    var $DESCRIPTION;
    var $TMP;

    
    function TXMLParser()
    {
        $this->FILE = "";
        $this->MODNAME = "";                        
        $this->VERSION = "";
        $this->AUTHOR = "";
        $this->DESCRIPTION = "";  
        $this->currentTag = "FILE";
        
        $this->xmlparser = xml_parser_create();    
        
        xml_set_object($this->xmlparser, &$this);
        xml_set_element_handler($this->xmlparser, Array(&$this, "startTagEdit"), Array(&$this, "endTagEdit"));
        xml_set_character_data_handler($this->xmlparser,  Array(&$this, "dataEdit"));
    }                                                        
    
    function startTagEdit($parser, $tagname)
    {
        /* DEBUG */
        print ("<br> \t"."&lt;".$tagname.">"."\r\n");
        /* DEBUG */
        
        // Узнаю что за информация о моде
        $this->currentTag =  $tagname;
    }

    function endTagEdit($parser, $tagname)    
    {
        /* DEBUG */
        print ("<br> \t"."&lt;/".$tagname.">"."\r\n");
        /* DEBUG */
        $this->currentTag = "TMP";    
    }
    
    function dataEdit($parser, $data)
    {                                     
        /* DEBUG */
        print ("<br> \t".$data."\r\n");
        /* DEBUG */

        /* Записываю информацию в поле
        которое указано в currentTag */
        if (($this->currentTag != "MOD") && ($this->currentTag != "TMP"))
        {
            $currentTag = $this->currentTag;
            $this->{$currentTag} = $data; # {"File"} = $($currentTag = "File)
            
            /* DEBUG */                        
            /*foreach (get_declared_classes() as $a)
            {
                print "<br>--a = ".$a;
            }                      
            
            $a = get_object_vars($this);
            while (list($key, $value) = each($a))
            {
                print "<br>--$key = ".$value;
            }    */
            #print "<br> class this :: ".get_class($this);
            print "<br> \$currentTag = $currentTag"."\r\n";
            print "<br>\$this->{\$currentTag} = ".$this->{$currentTag}."\r\n";
            #print ("<br> \t"."\$this->currentTag : ".$this->currentTag."\r\n");  
            /* DEBUG */
        }

    }
    
    //XML Parse
    function parse($fn)
    {
        /* DEBUG */
        print ("<br><b><hr></b>\r\n");        
        print ("<br><br> \t"."<b>-\$fn=".$fn."</b>\r\n");
        /* DEBUG */
    
        // открываю файл
        $fp = fopen($fn, "r");
        
        // парсю каждую строку
        while ($line = fgets($fp, 4096))
        {
            /* DEBUG */
            #print ("<br> \t"."-line=".$line."\r\n");
            /* DEBUG */
            
            if (! xml_parse($this->xmlparser, $line, feof($fp))) 
            {
             // ошибки умалчиваем
            /* DEBUG */
            print ("<br> \t"."parce error=".xml_error_string(xml_get_error_code($this->xmlparser))." in line=".xml_get_current_line_number($this->xmlparser)."\r\n");
            /* DEBUG */
             continue;    
            } 
        }      
        /* DBUG */
        /* $a = get_object_vars($this);
        
        while (list($key, $value) = each($a))
        {
            print "<br>--$key = ".$value;
        }    */
        /* DBUG */
     }    
     
}  // End TXMLParser
   
class TMod
{
 var $File;
 var $ModName;
 var $Path;
 var $Version;
 var $Size;
 var $Author;
 var $Description;
 function TMod() {}
}

function AddModInfo($file, &$filelist)
{    
    /* DEBUG */
    #print ("<br> >START XML Parse"."\r\n");
    /* DEBUG */
    $ModInfo = new TXMLParser;
    $ModInfo->parse($file);
    xml_parser_free($ModInfo->xmlparser);
    
    /* DEBUG */
    #print ("<br> -\$file: ".ereg_replace("(.{3})$", basename($file), "")."\r\n");
    /* DEBUG */
    
    /* DEBUG */
    print ("<br> <b>=\$ModInfo=</b>");
    
    $a = get_object_vars($ModInfo);
    while (list($key, $value) = each($a))
    {
        print "<br>--$key = ".$value;
    }      
    print ("<br><b><hr></b>\r\n");
    /* DEBUG */                                                      
    
    $Mod = new TMod;
    $Mod->Path = dirname($file).$GLOBALS["razdel"];
    $Mod->File = $ModInfo->FILE;
    
    /* DEBUG */
    #print ("<br> -filename: ".$Mod->Path.$Mod->File."\r\n");
    /* DEBUG */       
    
    // Проверю - есть ли сам мод
    if (file_exists($Mod->Path.$Mod->File)) 
    {
        $Mod->ModName = $ModInfo->MODNAME;
        $Mod->Version = $ModInfo->VERSION;
        $Mod->Author = $ModInfo->AUTHOR;
        $Mod->Description = $ModInfo->DESCRIPTION;      
        $Mod->Size = filesize($Mod->Path.$Mod->File); 
        array_push($filelist, $Mod);

        /* DEBUG */
        #print (" modname=".$Mod->File."  size=".$Mod->Size."\r\n");
        /* DEBUG */
    }
        

}

function buildfilelist($dir, $filelist)
{    
    if (!is_dir($dir)) {print("<b><h1><font color='#FF0000'>wrong folder: $dir</font></h1></b>"); return false;}
    
    
    $dh = opendir($dir);    
    while ($file = readdir($dh))  
    {                              
        /* DEBUG */
        #print ("<br> <font color='#3366CC'><h4>$dir$file</h4></font>\r\n");
        /* DEBUG */
        
        if (($file != ".") && ($file != ".."))
        {
            /* DEBUG */
            #print ("<br> <h4>$dir$file</h4>\r\n");
            /* DEBUG */
            
            if (is_dir($dir.$file))
            {
                $filelist = buildfilelist($dir.$file.$GLOBALS["razdel"], $filelist);
            }
            else
            {    
                /* DEBUG */
                #print ("<br> <b>selected file ^^</b> ");
                /* DEBUG */
                
                // ищу все xml'ки
                if (ereg("(.+)(\.xml$)", $file)) 
                {
                    AddModInfo($dir.$file, &$filelist);
                    
                    /* DEBUG */
                    #print ("<br> modinfo: ".$file."\r\n");
                    /* DEBUG */
                }
            }    
        }
    }
    
    return $filelist;
}

function getModList()
{
    $filelist = array();
    // типа тут просматриваю все папки.
    return buildfilelist($GLOBALS["root_folder"], $filelist);
}


function CreateModList()
{
    print "<?xml version='1.0' encoding='WINDOWS-1251'?>\r\n";
    $repository_name = $_SERVER['DOCUMENT_ROOT'];
    print "\t<repository name=' $repository_name'>\r\n";
    
    $ModList = getModList();
    if ($ModList):
        foreach ($ModList as $NextMod) 
        {
            print ("\t\t<mod modname='$NextMod->ModName' path='$NextMod->Path' version='$NextMod->Version' size='$NextMod->Size' author='$NextMod->Author'>$NextMod->Description</mod>\r\n");    
        }              
    endif;
    
    print "\t</repository>\r\n";
}

CreateModList();
?>


Результат: http://aanda.fatal.ru/sserver.php
Что делать?! Необходимо, что бы этот скрипт заработал на PHP 4 версии, но отказываться от классов нельзя -((


Это сообщение отредактировал(а) Deja_Vu - 10.7.2007, 21:50
PM Skype   Вверх
sTa1kEr
Дата 10.7.2007, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Сразу подумал, что все проблеммы из-за того, что в PHP 4 объекты по умолчанию передаются по значению, а не по ссылке, но решил проверить. Очень неординарно ведет себя PHP 4. Проблемы оказалась в самом неожиданном месте, в строчках 47 и 48:
Код

        xml_set_element_handler($this->xmlparser, Array(&$this, "startTagEdit"), Array(&$this, "endTagEdit"));
        xml_set_character_data_handler($this->xmlparser,  Array(&$this, "dataEdit"));

Хотя, по идеи, конструкции типа  Array(&$this, "startTagEdit") правильные и $this в массив устанавливается по ссылке, но! в xml_set то-ли по дороге ссылка в массиве теряется, то-ли ссылки в xml_set_object и других xml_set разные оказываются... Однако если поместить эти строчки перед самим xml_parse(), то, как ни странно, все работает. 

Но наиболее правильный вариант - это передавать стоки вместо массивов. Т.е. вместо строчек 47 и 48:
Код

        xml_set_element_handler($this->xmlparser, "startTagEdit", "endTagEdit");
        xml_set_character_data_handler($this->xmlparser,  "dataEdit");

Видимо в этом случае он сам определяет, что это методы нужного класса и сам правильно сохраняет нужные ссылки.

Добавлено @ 00:09
Да, совем забыл. Еще один момент. Т.к. xml_parser() парсит теги построчно (как не странно, то что вы вызываете его для каждогой строки отдельно - тут непричем), то для одного тега он может вызывать метод dataEdit() несколько раз. Eсли к примеру теги будут вида:
Код

<MODNAME>
    My Module
</MODNAME>

То он сначала запишет в поле MODNAME "My Moduel", а затем перезапишет его переносом строки. По этому, желательно проверять, что он второй раз пишет в один тег. К примеру, добавить в начало метода:
Код

        $data = trim($data);
        if (empty($data)) return;


Это сообщение отредактировал(а) sTa1kEr - 11.7.2007, 00:10
PM MAIL   Вверх
Deja_Vu
Дата 11.7.2007, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 15.6.2007
Где: Казань

Репутация: нет
Всего: 2



хм ... да уж.. неожиданна развязка - пасибо.

Цитата
То он сначала запишет в поле MODNAME "My Moduel", а затем перезапишет его переносом строки. По этому, желательно проверять, что он второй раз пишет в один тег. К примеру, добавить в начало метода:
Неа.. он не такой тупой -)) Проверенно.
Просто втоой раз эта функция вызывается вне - после закрывающего тега.

Это сообщение отредактировал(а) Deja_Vu - 11.7.2007, 00:19
PM Skype   Вверх
sTa1kEr
Дата 11.7.2007, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Цитата(Deja_Vu @  11.7.2007,  00:18 Найти цитируемый пост)
Неа.. он не такой тупой -)) Проверенно.
Просто втоой раз эта функция вызывается вне - после закрывающего тега.

У меня перезаписал smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0957 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.