Jump to content
  • 0

Осваиваю PHP и разбираю пример гостевой книги от IT-Soft


Anthony
 Share

Question

Дошел до места, где непонятно следующее..

/* открываем директорию и считываем из нее файлы */

$dir_rec = dir("records");

$i = 0;

while($entry = $dir_rec->read())

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - это что за запись?

{

if (substr($entry,0,3)=="rec")

{

$names[$i]=substr($entry,4);

$i++;

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ логика условия тоже неочень понятна.

}

}

Link to comment
Share on other sites

23 answers to this question

Recommended Posts

  • 0

$entry = $dir_rec->read()

читаем имя следующего файла/каталога в папке ?records?. Если кончилось, то получим false, именно false (то есть в коде есть маленький баг).

substr($entry,0,3)=="rec"

в переменной $entry у нас хранится имя файла/каталога. Соответственно, предыдущий код проверяет первые три символа в имени ? если это "rec", то в массив $names добавляем следующий элемент ? строка, состоящая из имени файла/каталога с отсеченными первыми тремя буквами

Link to comment
Share on other sites

  • 0

Конечно, не хочется зазубривать готовыми конструкциями, - хочется разобраться в деталях.

>$entry = $dir_rec->read()

Откуда следует, что это чтение именно следующего файла?

Что вообще за оператор "->" ? Я встречал в массивах только "=>"

Далее, команда read() она вообще откуда?

В документации о ней я не нашел ни слова (конкретно в разделе, посвященному "dir").

С условием так и не понял.. Зачем какой-то "rec"?

Кто-то к чему прибавляется, при этом отсекается..

В PHP всегда такие заморочки? Нет более понятного способа считать файлы из каталога?

Link to comment
Share on other sites

  • 0
$entry = $dir_rec->read()

Откуда следует, что это чтение именно следующего файла?

Порядок считывания файлов определяется порядком их нахождение в ОС

Что вообще за оператор "->" ? Я встречал в массивах только "=>"

Далее, команда read() она вообще откуда?

-> ? говорит php, что следует обратиться к методу или свойству какого-то класса. В данном случае, классом является dir, а read() метод этого класса. (формально ? это не ООП конечно)

В документации о ней я не нашел ни слова (конкретно в разделе, посвященному "dir").

Внимательней надо смотреть :)

С условием так и не понял.. Зачем какой-то "rec"?

Кто-то к чему прибавляется, при этом отсекается..

В PHP всегда такие заморочки? Нет более понятного способа считать файлы из каталога?

Для этого надо видеть код целиком. Здесь нет заморочек :) Есть более понятный способ ? opendir(), readdir(), closedir()?

Link to comment
Share on other sites

  • 0

А это нормально, что если стоит задача считать какие-то данные, то в php это делается через прогон цикла?

Мне кажется, здесь определяющую роль играет авторский подход, - кому-то нравится так, кому-то так, при этом, у каждого в голове свои тараканы, и въехать в ход мыслей каждого не так просто...

Когда читаешь разъяснение команд и операторов, вроде бы понятно.

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

Link to comment
Share on other sites

  • 0

2Anthony: Это заморочки не ПХП, а программирования. Знал же, куда лезешь, зачем лез?

Очевидно, сообщения в гостевой сохраняются в отдельные файлы каталога records. Для того, чтобы их отличать от остальных файлов, им приписывается префикс rec. Во время считывания файлов из каталога, они фильтруются по этому префиксу. Имена нужных файлов сохраняются в массив.

И не надо писать, что ничего не написано.

В мануале русским языком сказано:

class dir {
dir ( string каталог ); // конструктор класса
string path; // свойство, содержащее путь
resource handle; // свойство, содержащее дескриптор каталога
string read ( void ); // метод аналог http://www.php.net/manual/ru/function.readdir.php
void rewind ( void ); // метод аналог http://www.php.net/manual/ru/function.rewinddir.php
void close ( void ); // метод аналог http://www.php.net/manual/ru/function.closedir.php
}

Я уже писал, что read() - это метод класса dir.

Символом "->" происходит обращение к свойствам и методом класса.

Смотри мануал по ООП в PHP. Хоть dir - это и псевдокласс, тем не менее.

dir - это абстракция над функциями opendir(), readdir(), rewinddir() и closedir(). Чтобы удобнее работать было и не следить за дескриптором.

Link to comment
Share on other sites

  • 0
А это нормально, что если стоит задача считать какие-то данные, то в php это делается через прогон цикла?

Мне кажется, здесь определяющую роль играет авторский подход, - кому-то нравится так, кому-то так, при этом, у каждого в голове свои тараканы, и въехать в ход мыслей каждого не так просто...

А как это делается в других языках? Можешь, конечно, рекурсивную функцию замутить. Правда памяти и ресурсов сожрет много.

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

Когда читаешь разъяснение команд и операторов, вроде бы понятно.

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

У тебя незаурядный экспириенс. Но, не расстраивайся. Со временем это пройдет. Главное, руки не опускай, а то это может завести на нехорошие сайты.

Link to comment
Share on other sites

  • 0

Kel-Tanas, мне казалось, что данный пример остался со времен php младше версии 4.3.

Сейчас все это возможно сделать используя функцию glob, которая все найдет по ?маске? и даст результат сразу в массив. Просто хотелось, чтоб человек понял код, который привел.

$names = glob("records/rec*");

______________________________________

Добавлено:

Весь начальный код можно заменить (попробовать, во всяком случае) на

$names = glob("records/rec*");
$i = 0;
while( isset($names[$i++]) ) $names[$i-1] = substr($names[$i-1], 11);

Link to comment
Share on other sites

  • 0

>Это заморочки не ПХП, а программирования. Знал же, куда лезешь, >зачем лез?

Вопрос риторический..

>Очевидно, сообщения в гостевой сохраняются в отдельные файлы >каталога records. Для того, чтобы их отличать от остальных файлов, им >приписывается префикс rec. Во время считывания файлов из каталога, >они фильтруются по этому префиксу. Имена нужных файлов >сохраняются в массив

Если им приписывается одинаковый префикс, как же они тогда отличаются?

>И не надо писать, что ничего не написано.

>В мануале русским языком сказано:

> dir ( string каталог ); // конструктор класса

> string path; // свойство, содержащее путь

> resource handle; // свойство, содержащее дескриптор каталога

> string read ( void ); // метод аналог http://www.php.>net/manual/ru/function.readdir.php

> void rewind ( void ); // метод аналог http://www.php.>net/manual/ru/function.rewinddir.php

> void close ( void ); // метод аналог http://www.php.net/manual/ru/function.>closedir.php

Видимо, у нас разные источники.

>Я уже писал, что read() - это метод класса dir.

>Символом "->" происходит обращение к свойствам и методом класса.

>Смотри мануал по ООП в PHP. Хоть dir - это и псевдокласс, тем не >менее.

>dir - это абстракция над функциями opendir(), readdir(), rewinddir() и >closedir(). Чтобы удобнее работать было и не следить за >дескриптором.

Проблема в том, что когда я по главам читал документацию, как раз раздел с ООП показался мне невнятным и я его (по совету знающих людей, - мол, иди далее, как специфику поймешь, будет понятен и синтаксис ООП) пропустил. Теперь понимаю, что неясностей стало еще больше :-|

Особенно после фразы, что dir - это абстракция над функциями..

Link to comment
Share on other sites

  • 0

>А это нормально, что если стоит задача считать какие-то данные, то в >php это делается через прогон цикла?

>Мне кажется, здесь определяющую роль играет авторский подход, - >кому-то нравится так, кому-то так, при этом, у каждого в голове свои >тараканы, и въехать в ход мыслей каждого не так просто...

>А как это делается в других языках? Можешь, конечно, рекурсивную >функцию замутить. Правда памяти и ресурсов сожрет много.

>В том-то и прелесть, что каждый может использовать свой креатив. >Пожалуйста, как бы ты прочитал содержимое каталога без >использования цикла?

Как можно задать функцию рекурсивно?

Что это вообще за прием?

>Когда читаешь разъяснение команд и операторов, вроде бы понятно.

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

>У тебя незаурядный экспириенс.

А что в нем незаурядного?

Может я не тем путем иду?

С другой стороны, не думаю, что в PHP есть что-то такое, что недоступно для человека с высшим образованием...

>Но, не расстраивайся. Со временем это пройдет.

>Все-таки время тут непричем..

>Вот когда детали будут ясны, тогда придет и внутреннее >удовлетворение. А пока я даже образно представить себе это не могу, >мне кажется, здесь много лишнего.. и наверняка есть способ проще и .>_конкретнее_.

>Главное, руки не опускай, а то это может завести на нехорошие сайты.

Т.е. ?? Причем тут нехорошие сайты?

Вот я и не знаю, толи материал ООП через себя пропускать, то ли искать описание и пробовать применять рекомедованные команды.

Если брать новое и вставлить в код, уверен, скрипт "встанет".

Link to comment
Share on other sites

  • 0

> Если им приписывается одинаковый префикс, как же они тогда отличаются?

Допустим, пользователь добавляет новую запись в гостевую.

Таким образом можно создать файл, с уникальным именем, начинающимся на rec

$sNewFileName = 'rec'.time().xml;

Тогда файл будет иметь примерно такое имя "rec1178335179.xml", начинающееся на rec и при этом уникальное.

К тому же из имени файла всегда будет ясна дата его создания в секундах )))

ООП пропускать не в коем случае нельзя. Надо сидеть и разбираться. Терпение и труд все перетрут.

Link to comment
Share on other sites

  • 0
vartem, давайте, тогда уж и массив перебирать foreach-ем, а не while-ом, словно программисты каменного века.

while теперь в прошлом веке, оказывается. Мне просто, кажется, что while сработает в данном случае быстрее, хотя в современном мире, с такими мощностями, ? какая разница?

ООП пропускать не в коем случае нельзя. Надо сидеть и разбираться. Терпение и труд все перетрут.

Абсолютно согласен с этим.

Kel-Tanas, куда-то нас занесло :) ну да ладно?

Link to comment
Share on other sites

  • 0
while теперь в прошлом веке, оказывается. Мне просто, кажется, что while сработает в данном случае быстрее, хотя в современном мире, с такими мощностями, ? какая разница?

Нет, не в прошлом. Но для массивов есть специальный цикл. Его и рекомендуется использовать.

Еще можно

reset($array); 
while(list($key, $val) = each($array));

Но это менее удобно. Ну никак не перебором индексов. Ведь достоверно неизвестно, какие индексы присутствуют, а какие нет.

Вот если есть массив

$a = array(1=>'a', 2=>'b', 4=>'d', 5=>'e');

Вопрос на засыпку. Какие элементы этого массива переберет твой код?

А что в нем незаурядного?...

Т.е. ?? Причем тут нехорошие сайты?...

Шутка.

Рекурсивная функция, которая вызывает сама себя n-ое количество раз. А потом возвращается обратно.

function recurs($i)
{
if ($i >0) {
print $i.' ';
recurs(--$i); // вызываем с параметром на 1 меньше
}
}
recurs(10);

Link to comment
Share on other sites

  • 0
Но для массивов есть специальный цикл. Его и рекомендуется использовать.

Еще можно

reset($array); 
while(list($key, $val) = each($array));

Специальный цикл для массивов? Поясните, пожалуйста, правда интересно? Давайте откажемся от foreach при работе с классами, в этом случае? Или воспользуемся array_walk, чтобы совсем все усложнить, ? однако используем функцию, предназначенную именно для массивов?

Кем рекомендуется? Я не зря написал про время выполнения. Не поленился и проверил (провел тест над каталогомами, в которых более 2к файлов) ? из трех (наверное, пока) конструкциий: while( isset($names[$i++]) ), foreach($names as &$v) и while(list($key, $val) = each($array)) ? лучшую производительность показывает именно первая, самая простая конструкция.

Ведь достоверно неизвестно, какие индексы присутствуют, а какие нет.

Вот если есть массив

$a = array(1=>'a', 2=>'b', 4=>'d', 5=>'e');

Вопрос на засыпку. Какие элементы этого массива переберет твой код?

Ну почему же? Достоверно известно, что результатом будет пустой массив (если ничего не нашлось) или простой индексированный массив от 0 с дальнейшим увеличением индекса на 1. Здесь я, кстати, согласен: если бы был ассоциативный (смешанный и т.п.) массив, то foreach ? лучший выбор по всем показателям. Даже приведенный массив $a обработается foreach`ом, благо ? такого не получится и while переберет все найденные имена файлов.

Link to comment
Share on other sites

  • 0
Давайте откажемся от foreach при работе с классами, в этом случае? Или воспользуемся array_walk, чтобы совсем все усложнить, ? однако используем функцию, предназначенную именно для массивов?

Это уже, как угодно. Но, думаю, обсуждения интерфейса Iterator в этой ветке уже неуместно. В противном случае заниматься перебором свойств - дело не совсем благодарное.

И не пойму, чем не нравится array_walk(). Правда, foreach, конечно, сподручней, чем писать обработчик для каждого массива. Но, тут уже зависит от образа мышления программиста и конкретного случая. Если одни и те же действия над элементами массива необходимо провести в различных местах программы несколько раз, то проще написать один раз обработчик для array_walk() и использовать его.

Конструкция while( isset($names[$i++]) ) логически неверна для перебора массива. Т.к. если в массиве не будет хватать хотя бы одного элемента где-нибудь по-середине, это приведет к краху алгоритма и логической ошибке, которую найти будет не просто.

Link to comment
Share on other sites

  • 0
лучшую производительность показывает именно первая, самая простая конструкция.

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

Link to comment
Share on other sites

  • 0

Kel-Tanas, у меня такое ощущение, что мы о разных вещах. Вы говорите, как лучше применять в ?общем? случае ? причем я не раз уже соглашался с Вами; я говорю о конкретном случае, привел доводы (которые Вы почему-то переносите опять же на ?общий? случай) и никак не пойму в чем проблема ? поэтому дальнейшего желания продолжать тему у меня нет.

Link to comment
Share on other sites

  • 0

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

если новичок сделает из гостевой форум это значит есть мозги))

кста, вас вовсе новичками не считаю, это общее рассуждение..

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy