PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи

Страниц (594): « 1 2 3 [4] 5 6 7 8 9 ... » В конец

> Найдено сообщений: 8901
EuGen Отправлено: 04 Мая, 2014 - 18:53:36 • Тема: Украина в огне • Форум: Прочее

Ответов: 56
Просмотров: 368
Друзья!

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

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

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

Поэтому - я закрываю тему, но не из-за цензуры, а просто по причинам, изложенным мною выше. Надеюсь на понимание.
EuGen Отправлено: 25 Апреля, 2014 - 17:27:19 • Тема: Вывод дерева MySQL - Closure Table • Форум: Вопросы новичков

Ответов: 7
Просмотров: 1147
В первом листинге - да, названия должны быть обратными. Всё дерево и так выбирается одним запросом. Но если нужно именно строить его где-либо для рекурсивных процедур, то - как я уже и указал выше - либо начинать с листьев, либо хранить/вычислять уровни. Второе мне кажется наилучшим вариантом.

При этом я всё ещё рекомендую форматирование поручать приложению, так как это именно его работа. Выбрать через СУБД - можно, однако пользы в этом почти что нет. Тем более, что при двойной индексации выбранного дерева в приложении операции будут происходить очень быстро (так как мы используем хеш-выборки)
EuGen Отправлено: 25 Апреля, 2014 - 12:33:16 • Тема: Вывод дерева MySQL - Closure Table • Форум: Вопросы новичков

Ответов: 7
Просмотров: 1147
идея Closure table - хранить все узлы, стоящие выше по иерархии, чем тот, для которого нужно сделать запись. Это означает, что если у нас есть
PHP:
скопировать код в буфер обмена
  1.  
  2.     [P]
  3.    /   \
  4. [Q]    [R]
  5.       /   \
  6.    [S]     [T]
  7.  

То, например, для узла S записями будут
PHP:
скопировать код в буфер обмена
  1.  
  2. +--------+-------+
  3. | parent | child |
  4. +--------+-------+
  5. |   P    |   S   |
  6. +--------+-------+
  7. |   R    |   S   |
  8. +--------+-------+
  9. |   S    |   S   |
  10. +--------+-------+
  11.  

- сам себя узел тоже хранит. Поэтому, чтобы выбрать дерево для узла X, достаточно сделать запрос
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM closure_table WHERE parent=X

- это выдаст все узлы, у которых X является родителем-предком - таким образом, будут получены все узлы.

Для именно вывода дерева closure table подходит не так хорошо, однако ничто не мешает сделать несколько запросов, начиная с листьев. Например:

- Найти листья. Это те узлы, которые встречаются в таблице всего лишь раз (то есть запись самих себя). Это выглядит примерно так:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM closure_table WHERE parent=X GROUP BY parent HAVING COUNT(1)=1

- Выбрать узлы, которые будут иметь в родителях X, а в качестве потомков - найденные листья. Это будет запрос на WHERE IN .. - что хорошо выполнится через range scan. Найденные узлы нужно рассортировать по листьям, поскольку нужно строить дерево и просто уровня уже недостаточно. Это, скорее всего, будет поручено приложению.
- Повторить до тех пор, пока есть записи.

В общем-то, запросов будет не так и много, но всё же запрос не будет один (несмотря на то, что всё дерево можно получить одним запросом).

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

Так как построение дерева "с листьев" - в общем-то, не очень простая задача, то можно хранить длину пути, чтобы получить возможность строить дерево с корня.

Ниже приведу пример, как можно поступить в случае с приложением. Вообще говоря, нам вовсе не обязательно хранить уровень - его можно вычислить (однако, как правило, лучше хранить и пересчитывать, так как вычисляется он исходя из количества записей в child-поле для конкретного узла). В примере я так и поступлю - то есть, не буду хранить уровень отдельно. Предположим, у нас есть дерево:

PHP:
скопировать код в буфер обмена
  1.  
  2.    [P]
  3.   /   \
  4. [Q]    [R]
  5.       /   \
  6.    [S]     [T]
  7.               \
  8.                [U]
  9.  

Тогда пусть его представлением будет массив:
PHP:
скопировать код в буфер обмена
  1. $data = [
  2.    ['parent'=>'P', 'child'=>'P'],
  3.    ['parent'=>'P', 'child'=>'Q'],
  4.    ['parent'=>'Q', 'child'=>'Q'],
  5.    ['parent'=>'P', 'child'=>'R'],
  6.    ['parent'=>'R', 'child'=>'R'],
  7.    ['parent'=>'P', 'child'=>'S'],
  8.    ['parent'=>'R', 'child'=>'S'],
  9.    ['parent'=>'S', 'child'=>'S'],
  10.    ['parent'=>'P', 'child'=>'T'],
  11.    ['parent'=>'R', 'child'=>'T'],
  12.    ['parent'=>'T', 'child'=>'T'],
  13.    ['parent'=>'P', 'child'=>'U'],
  14.    ['parent'=>'R', 'child'=>'U'],
  15.    ['parent'=>'T', 'child'=>'U'],
  16.    ['parent'=>'U', 'child'=>'U']
  17. ];

- я записываю его напрямую, но ничто не мешает выбирать данные из БД. Тогда в приложении мы можем рекурсивно собрать данные в привычную структуру со смежными подчинёнными узлами. Для этого нужно построить индекс-таблицу, в которой будет считаться как уровень узла, так и храниться его связи с остальными. В моём примере индекс двунаправленный (родители -> потомки, потомки->родители):
PHP:
скопировать код в буфер обмена
  1.    protected function indexClosure()
  2.    {
  3.       $this->indexTable = [];
  4.       foreach($this->closureTable as $item)
  5.       {
  6.          $this->indexTable['parents'][$item['parent']][] = $item['child'];
  7.          $this->indexTable['childs'][$item['child']][]   = $item['parent'];
  8.          $this->indexTable['levels']['forward'][$item['child']]     =
  9.             isset($this->indexTable['levels']['forward'][$item['child']])
  10.                ?$this->indexTable['levels']['forward'][$item['child']]+1
  11.                :1;
  12.       }
  13.       foreach($this->indexTable['levels']['forward'] as $key=>$level)
  14.       {
  15.          $this->indexTable['levels']['backward'][$level][]=$key;
  16.       }
  17.    }

-выношу это отдельно, так как понимание структуры этой вспомогательной индекс-таблицы очень важно. По сути, работая с индексированной таблицей в СУБД будет выполняться примерно та же работа. Использовать это можно так:
PHP:
скопировать код в буфер обмена
  1.    public function closureToAdjanced($node)
  2.    {
  3.       if(!isset($this->indexTable['parents'][$node]))
  4.       {
  5.          return [];
  6.       }
  7.       $level  = $this->indexTable['levels']['forward'][$node];
  8.       $tree   = array_intersect(
  9.          $this->indexTable['parents'][$node],
  10.          $this->indexTable['levels']['backward'][$level+1]
  11.       );    
  12.       $result = count($tree)
  13.          ?array_combine(
  14.             $tree,
  15.             array_fill(1, count($tree), [])
  16.           )
  17.          :[];
  18.       foreach($result as $child=>$subtree)
  19.       {
  20.          if(count($this->indexTable['parents'][$child])>1)
  21.          {
  22.             $result[$child] = $this->closureToAdjanced($child);
  23.          }
  24.       }
  25.       return $result;
  26.    }

- то есть, проверить, не лист ли передан, и, если нет, пройтись по поддереву рекурсивно. Поддерево - это все подчинённые узлы, у которых уровень на +1 больше. На этом всё.

Полный код:
PHP:
скопировать код в буфер обмена
  1. class ClosureTree
  2. {
  3.    protected $closureTable = [];
  4.    protected $indexTable = [];
  5.    
  6.    public function __construct(array $table=[])
  7.    {
  8.       $this->closureTable = $table;
  9.       $this->indexClosure();
  10.    }
  11.  
  12.    public function closureToAdjanced($node)
  13.    {
  14.       if(!isset($this->indexTable['parents'][$node]))
  15.       {
  16.          return [];
  17.       }
  18.       $level  = $this->indexTable['levels']['forward'][$node];
  19.       $tree   = array_intersect(
  20.          $this->indexTable['parents'][$node],
  21.          $this->indexTable['levels']['backward'][$level+1]
  22.       );    
  23.       $result = count($tree)
  24.          ?array_combine(
  25.             $tree,
  26.             array_fill(1, count($tree), [])
  27.           )
  28.          :[];
  29.       foreach($result as $child=>$subtree)
  30.       {
  31.          if(count($this->indexTable['parents'][$child])>1)
  32.          {
  33.             $result[$child] = $this->closureToAdjanced($child);
  34.          }
  35.       }
  36.       return $result;
  37.    }
  38.    //reset index & build it
  39.    protected function indexClosure()
  40.    {
  41.       $this->indexTable = [];
  42.       foreach($this->closureTable as $item)
  43.       {
  44.          $this->indexTable['parents'][$item['parent']][] = $item['child'];
  45.          $this->indexTable['childs'][$item['child']][]   = $item['parent'];
  46.          $this->indexTable['levels']['forward'][$item['child']]     =
  47.             isset($this->indexTable['levels']['forward'][$item['child']])
  48.                ?$this->indexTable['levels']['forward'][$item['child']]+1
  49.                :1;
  50.       }
  51.       foreach($this->indexTable['levels']['forward'] as $key=>$level)
  52.       {
  53.          $this->indexTable['levels']['backward'][$level][]=$key;
  54.       }
  55.    }
  56. }

И, как пример использования:
PHP:
скопировать код в буфер обмена
  1. $tree = new ClosureTree($data);
  2. var_dump($tree->closureToAdjanced('P'));


Результатом будет привычное
PHP:
скопировать код в буфер обмена
  1. array(2) {
  2.   ["Q"]=>
  3.   array(0) {
  4.   }
  5.   ["R"]=>
  6.   array(2) {
  7.     ["S"]=>
  8.     array(0) {
  9.     }
  10.     ["T"]=>
  11.     array(1) {
  12.       ["U"]=>
  13.       array(0) {
  14.       }
  15.     }
  16.   }
  17. }

- которое уже можно рекурсивно обходить, чтобы строить нужные отступы/форматирование.
EuGen Отправлено: 18 Апреля, 2014 - 19:53:00 • Тема: рекурсивно получить файлы и папки начиная с указанной директории • Форум: Работа с файловой системой и файлами

Ответов: 2
Просмотров: 1178
0, 1, 2, ... ,
EuGen Отправлено: 17 Апреля, 2014 - 09:51:27 • Тема: Значение элемента массива как имя переменой • Форум: Вопросы новичков

Ответов: 4
Просмотров: 209
Что такое set_value?
Почему правила валидации не в виде хотя бы массива, например,

PHP:
скопировать код в буфер обмена
  1. 'rules' => array(
  2.    'required' => true,
  3.    'max_length' => 255
  4. )
  5. //...


Для чего нужна функция text() - обычный рендеринг? Тогда почему отрисовка поля включает в себя элементы внешнего форматирования (таблицы)?
EuGen Отправлено: 04 Апреля, 2014 - 17:14:27 • Тема: Ассоциативный массив из другого. Ключи типа int • Форум: Программирование на PHP

Ответов: 1
Просмотров: 248

?
EuGen Отправлено: 03 Апреля, 2014 - 22:44:09 • Тема: Узнать количество одинаковых элементов в массиве • Форум: Вопросы новичков

Ответов: 2
Просмотров: 293
PHP 5.5:
PHP:
скопировать код в буфер обмена
  1. //$array - исходный массив
  2. $result = array_count_values(array_column($array, 'status'));

PHP <5.5
PHP:
скопировать код в буфер обмена
  1. //$array - исходный массив
  2. $result = array_count_values(array_map(function($x)
  3. {
  4.    return $x['status'];
  5. }, $array));

?
EuGen Отправлено: 02 Апреля, 2014 - 12:43:39 • Тема: API Яндекс переводчик • Форум: Напишите за меня, пожалуйста

Ответов: 1
Просмотров: 22
Во Freelans
EuGen Отправлено: 01 Апреля, 2014 - 22:17:55 • Тема: Теперь я Zend Certified PHP Engineer ;) • Форум: Прочее

Ответов: 18
Просмотров: 172
teddy пишет:
Я рад, что Ваши сомнения в отношении меня рассеялись.

В отношении Вас - сомнений никогда и не было. В отношении обстоятельств - возможно, и были.

teddy пишет:
ООП как раз таки есть там и не мало

Нет. Знание структуры классов или, например, областей видимости/ключевых слов и их применения - это не ООП. Но это уже - достаточно близко к содержимому ZCE, так что не буду развивать эту тему.
EuGen Отправлено: 01 Апреля, 2014 - 21:30:37 • Тема: Теперь я Zend Certified PHP Engineer ;) • Форум: Прочее

Ответов: 18
Просмотров: 172
Нет. Я ошибся. Мои данные - устарели. ZCE 5.5 действительно не включает в себя вопросы, которые я озвучил. И действительно по большей части это - знание страниц мануала и правильных способов применения тех или иных конструкций. Это включает в себя новые возможности 5.4 и 5.5, но не включает концептуальных и фундаментальных вопросов наподобие паттернов, ООП, хороших/плохих практик и их производных или же программирования в целом, абстрагируясь от PHP. Относительно Энтони - возникло недопонимание, поэтому стоит исключить его из данного вопроса (наверное, не очень правильно было на него ссылаться, однако же - я не хотел быть голословным)

Кроме того, Pearson Vue - это авторизованный центр для проведения тестов по сертификации Zend. Эти мои сомнения были не обоснованы (хотя и исходили из сильного противоречия, возникшего у меня, которое я и описал выше - а, так как я действительно не сомневался в Ваших усилиях, выходом было лишь - подвергнуть сомнению центр тестирования). И - существует только один сертификат Zend.

Поэтому - поздравляю с успешной сдачей (хотя, поздравить стоило в любом случае) и получением статуса ZCE.
EuGen Отправлено: 01 Апреля, 2014 - 20:34:41 • Тема: Теперь я Zend Certified PHP Engineer ;) • Форум: Прочее

Ответов: 18
Просмотров: 172
teddy пишет:

Взаимоисключающие фразы. То Вы намекаете на то, что верите моим словам, то говорите, что есть сомнения. Вы уж определитесь.

Нет. Я всего лишь хотел бы увидеть сертификат (чтобы, в случае чего - мог его показать соавтору и убедиться - что - да, это тот самый сертификат. И - да, я понимаю, что сию минуту его ещё нет). Я допускаю, что соавтор экзамена мог многократно ошибиться при сдаче - однако факт есть факт - мои сведения отличаются от Ваших. То есть, мои сведения - экзамен по 5.5 настолько сложен и обширен, что даже те, кто причастен к его созданию - не имеют гарантии успешного прохождения. Он включает в себя не только эмпирические знания из страниц руководства или общеизвестные примеры. То есть, насколько мне известно, ZCE 5.5 нельзя просто "выучить" перед экзаменом.

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

teddy пишет:
Нет желания быть инструментом для Ваших "поддевок".

Видимо, я был неверно понят. Однако прошу понять и меня. С одной стороны - человек из разряда Энтони Феррара (ссылки удалены для исключения индексирования), который сейчас работает в google. Быть справедливым - это человек, который стоит в авангарде разработки PHP и даже разрабатывает новые концепты разработки в одном ряду с ООП. Ну - честно, мне трудно поверить, что он так сильно "ошибся". С другой стороны - Ваша активность на конференции. Я не хочу умалять Ваших успехов, но у того человека мне есть чему поучиться - и, даже сказать больше, мне до него очень далеко.

Может быть, я зря опираюсь на мнение третьей стороны. Но - увидим (если, конечно, Ваш предыдущий комментарий не означал полное нежелание вести дальнейший диалог). Да, кстати - если я и усомнился - то в центре тестирования, но не в Вас. Я уверен, что Вы готовились и потратили время на этот экзамен.

Поэтому - не ставя под сомнение Ваши успехи - я всего лишь хочу всё выяснить. Возможно, речь идёт вообще о разных сертификациях? Тогда я уточню это у Энтони (Anthony Ferrara) и всё встанет на свои места. Ещё раз прошу прошения, если моё предыдущее сообщение выглядело оскорбительным или провокационным. Надеюсь, что никто из посетителей конференции не обвинит меня в подобных вещах - но, в свою очередь, тоже не хочу быть в позиции оправдывающегося. Это важно для меня - и я хочу всё обстоятельно изучить и понять.
EuGen Отправлено: 01 Апреля, 2014 - 12:34:42 • Тема: Теперь я Zend Certified PHP Engineer ;) • Форум: Прочее

Ответов: 18
Просмотров: 172
Занятно. Видимо, ZCE - разные. Хотелось бы увидеть Ваш сертификат. Не подумайте, что это из недоверия, но просто - человек, с которым я знаком - и написавший ~30% вопросов к ZCE 5.5 - его не сдал. Отсюда возникают сомнения, прежде всего, в центре тестирования.

Я тоже не планирую идти на сертификацию 5.5, так как нужны весьма обширные практические познания. Не хотелось бы думать на плохое - поэтому мне правда интересно увидеть сертификат (он унифицирован, так что будет чем поддеть одного из авторов ZCE, если всё "в порядке")
EuGen Отправлено: 28 Марта, 2014 - 12:31:34 • Тема: Вопрос по Мат.операции и транзакции • Форум: Вопросы новичков

Ответов: 4
Просмотров: 186
Flash_PR пишет:
Т.е. грубо говоря есть какой-то временный файл с проделанными операциями, по которому сервер сверяется7

Это не файл по смыслу (но физически всё есть файл) - это данные, находящиеся в файлах тех инструметов СУБД, которые отвечают за контроль целостности транзакций.

"Среднее средних" - верно не во всех случаях

Если взять (A1 + A2 + ... + An) / n и затем среднее для первого члена и оставшейся суммы:

A1/1 + (A2 + ... +An)/(n-1) = ((n-1)A1 + A2 + ... + An)/(n-1)

Среднее этих средних есть

((n-1)A1 + A2 + ... + An)/(2n-2)

(так как слагаемых 2) - очевидно, это не равно исходному среднему. Простой пример: 3, 10, 5. Имеем:

(3 + 10 + 5) / 3 = 6,

однако

(3 + (10 + 5) / 2) /2 = 10.5/2 = 5.25 != 6
EuGen Отправлено: 28 Марта, 2014 - 12:27:06 • Тема: Вопрос по Мат.операции и транзакции • Форум: Вопросы новичков

Ответов: 4
Просмотров: 186
Flash_PR пишет:
смысл транзакции либо все выполняется либо ничего. Но для выполнения серверу требуется время. Если во время транзакции вырубается питание сервера, а он допустим делал миллион insert-ов, и вот на полумиллионом вырубилось питание. Как я понимаю из теории транзакции, транзакции не прошла, но что станет с первыми insert-оми при включении сервера?

Зависит от того, как реализован storage-engine. Незавершённые транзакции, как правило, откатываются до того момента, когда данные находились в целостном состоянии (на начало транзакции). Для этого могут использоваться сегменты отката или прочие инструменты внутри СУБД. Впрочем, ничто не надёжно на 100%. и в случае повреждения этих инструментов контроля - данные будут повреждены безвозвратно.
EuGen Отправлено: 27 Марта, 2014 - 13:33:53 • Тема: Уникальный индекс для изменяемой записи • Форум: SQL и Архитектура БД

Ответов: 5
Просмотров: 41
Snewer пишет:
Скорость выборки по данному столбцу вырастет?

Нет. Скорость будет ровно такой же, как для обычного индекса. Отличие лишь в запрете дублей.

Надобность в индексе зависит от того, для чего Вы храните данные. Если просто ради самого хранения (то есто поиска не планируется) - индекс не нужен и даже вреден (поскольку замедляет вставки)

Страниц (594): « 1 2 3 [4] 5 6 7 8 9 ... » В конец
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB