Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Разное

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Perl
 
 автор: bronenos   (30.09.2008 в 17:37)   письмо автору
 
 


@answers = ();
$answidx = 0;

sub getCommentsTree
{
    ($topic, $parent) = @_;
    $commentRes = $DB->Query("select * from comments where topic='$topic' and parent='$parent' order by id");
    
    $idx = $answidx++;
    push @answers, [];

    push [$answers[$idx]], {
        // перенос данных
    } while (%comment = $commentRes->FetchHash);
    
    return $idx;
}


Я хочу получить в результате двойной массив @answers, по типу @answers[индекс] = список
Но ругается.. не знаю, как правильней написать.. пробовал по-разному.
Хелп кто может

  Ответить  
 
 автор: xx77   (30.09.2008 в 20:50)   письмо автору
 
   для: bronenos   (30.09.2008 в 17:37)
 

В Perl нет такого типа данных как многомерный массив
, поскольку он низкоуровневый по сравнению с php
#!/usr/bin/perl
#<?perl
@one = (1'odin'0x33'tri');
@
dva = (2'dva', @one);
# массив или список , что почти одно и то-же
print ( join '-', @dva ) . "\n";
print   
"\n";
# выведет  2-dva-1-odin-51-tri


%= @dva;
# хэш (ассоциативный массив)  по сути то-же самое
# только формируется так что-бы можно было применить 
# например keys  или values

for (keys %h) {  print $_  "\n"; }
# выведет  1 51 2
for (values %h){  print $_  "\n"; }
# выведет odin tri dva
for (%h) {  print $_  '-'; }
print   
"\n";
# выведет 1-odin-51-tri-2-dva-

# или нужен что-бы обратиться к элементу по имени
print $h{51}; 

Но в Perl есть удобные конструкции чтобы работать со срезами массивов или хэшей


Или юзать oop

примерно такой конструкцией например можно
получить срез являющийся массивом @h{@key_values} = @newlist

  Ответить  
 
 автор: bronenos   (30.09.2008 в 21:50)   письмо автору
 
   для: xx77   (30.09.2008 в 20:50)
 

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

P.S. Вкратце - строю древовидную систему комментариев, так вот каждый комментарий (хэш) имеет ключ, содержащий индекс, если -1, если комментариев к нему нет.
Позже в массиве ищется, если $answers[индекс] есть, то операции повторяются, опять поиск массива по индексу и так далее..

  Ответить  
 
 автор: exp   (01.10.2008 в 16:14)   письмо автору
 
   для: bronenos   (30.09.2008 в 21:50)
 

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

#<?perl
use DBI;
my $port 3306;
my $host      'localhost';  # имя сервера
my $dbname    'base';   # имя базы данных 
my $user_name "root";   # имя пользователя
my $password  "";     # пароль пользователя

my $dbh DBI->connect(
      
"dbi:mysql:dbname=$dbname;host=$host;port=$port",
      
$user_name$password);

 
my $sql $dbh->prepare("SELECT * FROM comments WHERE topic='$topic'
ORDER BY IF(parent AND parent <> id, parent+1, id)"
);
$sql->execute
 
my $numRows $sql->rows;
print 
'rows = ' $numRows "\n\n";
die if 
$nimRows 0;
  
my $names $sql->{'NAME'};
print 
join "\t", @$names;
print 
"\n___________________________________\n\n";
  while (
my $ref $sql->fetchrow_arrayref()) {
 print 
join("\t", @$ref) . "\n";
 }
die 
$sql->finish && $dbh-> disconnect ;

выполнить коммандой
>perl 1.pl
в коммандной строке

  Ответить  
 
 автор: bronenos   (01.10.2008 в 23:00)   письмо автору
 
   для: exp   (01.10.2008 в 16:14)
 

Я знаю, что не в теме будет вопрос, но не могли бы вы сказать, что именно позволяет делать это условие? Неужто подгрузить в древовидном порядке все записи? О.о

  Ответить  
 
 автор: exp   (01.10.2008 в 23:36)   письмо автору
 
   для: bronenos   (01.10.2008 в 23:00)
 

:)
просто тестил на своей таблице , в которой есть parent нули и цифры одни из тех что в id у тех что с нулями .
И ORDER BY p , IF(p, p, i)
выводило всё как надо .

Привели.бы примерчик того что возвращает такое ,
и ещё описание что в итоге-то должно быть , какого вида дерево :)

хотя так и не понятно это дерево всё в одном топике , или это дерево топиков , чего я и хотел спросить :)

  Ответить  
 
 автор: bronenos   (02.10.2008 в 23:17)   письмо автору
 
   для: exp   (01.10.2008 в 23:36)
 

Да в общем-то, мне кажется, результат что я хочу получить, можно сравнить с древовидной системой здесь.. относительно главных полей topic, id, parent (id родителя)

  Ответить  
 
 автор: SHAman   (03.10.2008 в 00:04)   письмо автору
 
   для: bronenos   (30.09.2008 в 17:37)
 

Квадратные скобки - это ссылка на массив. Я могу написать:

$array_ref = [1,2,3,4];
print $array_ref->[0];


Аналогично, фигурные скобки - ссылка на хэш.

$hashref = {alpha=>1, beta=>2};
print $hashref->{alpha};


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

@array = (1,2,3,4);
$array_ref = \@array;
print $array_ref->[1];


Еще нужно знать как разыменовать ссылку. Это совсем просто:

$array_ref = [1,2,3,4];
push @$array_ref, 5;


Если смотреть мнемонически, то $array_ref содержит АДРЕС, по которому лежит массив. А значок @ идет по этому адресу и этот массив получает. Если смотреть внимательно, можно увидеть, что для простой переменной $scalar действует то же правило. scalar содержит адрес переменной, а значок $ ее разыменовывает.

Иногда для избежания двусмыслености пишут так:

@{$array_ref}


Собственно, в общем случае, получение структуры данных в структуру Perl из БД выглядит как-то так:

my $struct = [];
while(my $res = $sth->fetchrow_hashref)    {
    push @$struct, $res;
}


В результате мы получим массив хэшей. Мы можем распечатать эти данные очень просто:

foreach my $rec (@$struct)    {
    print qq(Привет, $rec->{name}! Ты живешь по адресу: $rec->{adress}.\n);
    print qq(<br/><img src="./avatars/$rec->{avatar}"/>);
}


Если что, стучись - подскажу.

  Ответить  
 
 автор: bronenos   (03.10.2008 в 00:23)   письмо автору
 
   для: SHAman   (03.10.2008 в 00:04)
 

Это я знаю все.. но поскольку функция у меня рекурсивная, то возвращение ссылки на локальный хэш (а затем и операции над пустым содержанием локального адреса) роняют функцию.

  Ответить  
 
 автор: SHAman   (03.10.2008 в 11:57)   письмо автору
 
   для: bronenos   (03.10.2008 в 00:23)
 

Не понимаю проблемы совсем. Если хочешь - стукни в асю. Я просто не понимаю в чем задача.

  Ответить  
 
 автор: exp   (04.10.2008 в 22:50)   письмо автору
 
   для: SHAman   (03.10.2008 в 11:57)
 

наверное дерево по такому принципу что child должен всегда быть непосредственно после parent.

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


примерно так получилось без сортировки с кучей запросов для того чтобы вернуть несколько строк.
Но мне для непостояного применения , а только сортировать меню после изменения
здесь только WHERE id=9 и id и p_id строго идут первым и вторым
#<?pl
use Time::HiRes qwgettimeofday );
my ($sec$mic) = gettimeofday
# ВРЕМЯ 
my $port 3306;
my $host      'localhost';  # имя сервера
my $dbname    'new_base';   # имя базы данных
my $user_name "root";   # имя пользователя
my $password  "";     # пароль пользователя
my ($Colls$test )= (0''); #счётчики
my $dbh;

use 
DBD::mysql;
sub mysql_query( $ ) {
    
my $sql;
    
$sql $dbh->prepare$_[0] );
    
$sql->execute;
    return 
$sql
}
sub rcrs( $ ) { # Функция
    
my $p $_[0]; 
 if (
$test !~ /\b$p\b/) {
    
$test .= ' ' $p;
    
my $sql = &mysql_query("SELECT * FROM new_lib WHERE 1 AND p_id = $p");
    if ( 
$sql->rows 0) {
        while (
my $ref $sql->fetchrow_arrayref())
        { 
        print 
join("\t",  @$ref) . "\n";
        &
rcrs($$ref[0]);
        }
# не понял как сделать всё на sql-запросах HANDLE 
#    никак не хочет выбирать больше одного ряда 
# и можетбыть поэтому  работало ещё медленнее чем это :)
        
}
    }
 }
# end of функции

$dbh DBI->connect(
      
"dbi:mysql:dbname=$dbname;host=$host;port=$port"$user_name$password);
my $sql1 = &mysql_query('SELECT * FROM new_lib WHERE id=9 LIMIT 1');
print 
'Необнаружено раздела'
 
."\n" && goto GOTOVO if  1$sql1->rows;
 
$Colls $sql1->{'NUM_OF_FIELDS'}; 
my $ref1 $sql1->fetchrow_arrayref(); # ряд
my $par = $$ref1[1]; ## первый parent 
print 'fields = ' $Colls ";\t" 'first_id = ' $par "\n\n";
# print join("\t", @$ref1) . "\n"; 
&rcrs($$ref1[0]); #Вызов функции

GOTOVOmy ($sec2$mic2) = gettimeofday;
$sec2 -= $sec;
$mic2 -= $mic;
printf("\t----------------\n\t%.7f\n"$sec2 + ($mic2 /= 1000000));
# ВРЕМЯ
$sql1->finish && $dbh-> disconnect ;

но совсем не знаю какие ещё бывают модули для mysql , и тут много лишнего,
например if ($test !~ /\b$p\b/) {
$test .= ' ' . $p;
лишняя проверка было-ли уже id в предыдущих вызовах функции,
нерационально , но пока поправлю уже точно неактуально будет , если не уже )

  Ответить  
 
 автор: SHAman   (06.10.2008 в 13:02)   письмо автору
 
   для: exp   (04.10.2008 в 22:50)
 

Тебе не лень было использовать драйвер мускула напрямую?:) DBD = Data Base Driver. Для работы с БД обычно используется DBI (Data base interface), который уже работает с DBD::имя_базы

А в рекурсии ничего сложного.

$tree{$key}->{child} = get_child_for($key);

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования