Получение в чанке ссылки на текущую страницу с изм

Предположим, url текущей страницы имеет несколько параметров. В чанке указывается ссылка, которая должна загрузить эту же страницу, но с одним изменённым параметром
href="[[~[[*id]]? &page=`1`]]"
Можно ли что-нибудь такое сделать, чтобы все прочие параметры здесь не перечислять (их придётся передавать черех плейсхолдеры), а указать только тот, который меняется?
Cyrax_02
04 августа 2014, 13:37
modx.pro
11 026
0

Комментарии: 29

Евгений Дурягин
04 августа 2014, 20:17
0
Через parse_url можно получить компоненты URL
Через parse_str можно распарсить параметры в массив
Поменять в массиве нужные значения и собрать обратно в строку через http_build_query
Затем собрать URL.
Можно использовать http_build_url, но нужно PECL ставить
    Cyrax_02
    04 августа 2014, 20:35
    0
    Я хотел на уровне парсера modx это сделать. Только пока не научили его этому.

    Кодом, кодом и ещё раз кодом:
    return http_build_url($_REQUEST['QUERY_STRING'], array('page' => $page));
      Алексей
      05 августа 2014, 01:21
      +1
      как так не научили? а ты исходники смотрел?
      $modx->makeUrl($id, '', $modx->request->getParameters(), 'abs'))
        Cyrax_02
        05 августа 2014, 10:28
        0
        А это не на уровне парсера modx. Плюс долго выполняется из-за ряда дополнительных обращений к БД.
          Алексей
          05 августа 2014, 13:42
          0
          кстати да, вот это
          $modx->makeUrl($id
          как-то можно на pdoFetch сделать?
            Василий Наумкин
            05 августа 2014, 16:02
            0
            А зачем это делать на pdoFetch?

            Вот исходник метода makeUrl — там есть ровно один запрос для получения alias ресурса, и то, только в том случае, если запрошенного ресурса нет в текущей карте сайта.
              Cyrax_02
              05 августа 2014, 20:58
              0
              Ну так обращение к карте сайта в файле на диске и обращение к базе данных mysql — это всё обращение к диску. Т.е. под обращением к БД в контексте скорости следует понимать обращение к диску. А это — самое слабое звено…
                Василий Наумкин
                05 августа 2014, 21:02
                0
                Ну а так-то страница загружается вообще без запросов, да? Карту ресурсов MODX загружает из кэша при любом раскладе.

                А даже если и нет — что за бред, ты 0.0001 сек экономишь?
          Василий Наумкин
          05 августа 2014, 15:56
          0
          А это не на уровне парсера modx
          А на уровне чего это? Вставляешь код в сниппет и его запускает именно парсер.

          Плюс долго выполняется
          <?php
          define('MODX_API_MODE', true);
          require 'index.php';
          $modx->getRequest();
          $time = microtime(true);
          $url = $modx->makeUrl(1, '', $modx->request->getParameters(), 'full');
          
          echo microtime(true) - $time;
          Результат 0.0001220703125 — очень долго, да.

          из-за ряда дополнительных обращений к БД
          Да ладно? Добавь к коду выше
          echo $modx->executedQueries;
          и увидишь, что хоть с генерацией url, что без неё выполняется ровно 3 запроса в БД.

          В общем, предложенный метод через request самый верный.
            Cyrax_02
            05 августа 2014, 21:02
            0
            Только вот этот самый вызов сниппета, который выполняет парсер — это полноценное обращение к БД + создание объекта. Если в скрипте генерируется сотня ссылок с одним или несколькими изменяющимися параметрами, все эти вызовы сниппета приведут к ощутимым тормозам. Итого 300 запросов к БД.
              Василий Наумкин
              05 августа 2014, 21:08
              0
              Лютый бред.
              <?php
              define('MODX_API_MODE', true);
              require 'index.php';
              $modx->getRequest();
              $time = microtime(true);
              
              for ($i = 1; $i <= 300; $i++) {
              	$id = rand(1, 105);
              	$url = $modx->makeUrl($id, '', $modx->request->getParameters(), 'full');
              }
              
              echo microtime(true) - $time;
              300 случайных ссылок — 0.04 сек.

              Давай ты дальше рассказы про обращения к диску, БД и страшных тормозах будешь иллюстрировать цифрами?
                Василий Наумкин
                05 августа 2014, 21:25
                0
                Меняем на вызов сниппета:
                for ($i = 1; $i <= 100; $i++) {
                	$id = rand(1, 105);
                	$modx->runSnippet('Test', array('id' => $id));
                }

                Сам сниппет:
                return $modx->makeUrl($id, '', $modx->request->getParameters(), 'full');
                100 вызовов — 0.09 сек., 300 вызовов — 0.24 сек.

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

                На мой взгляд, это никак нельзя назвать «ощутимыми тормозами».
                  Cyrax_02
                  05 августа 2014, 21:28
                  0
                  В цикле 300 вызовов makeURL у меня занимает столько:
                  0.78527092933655

                  Ну а если вызывать через $modx->runSnippet — секунд 5 будет.
                    Василий Наумкин
                    05 августа 2014, 21:36
                    0
                    Сочувствую. Нужно сменить или хостинг, или логику работы.

                    Можно вызвать сниппет 1 раз, чтобы он выставил плейсхолдер со строкой параметров для всех ссылок.
                      Cyrax_02
                      05 августа 2014, 22:40
                      0
                      Ещё раз проверил:
                      300 вызовов makeUrl — 0.7-0.8 сек, 300 вызовов runSnippet — 1.2-1.4 сек.

                      Вообще, сабжевую задачу я уже решил. makeURL вызываю 1 раз, чтобы получить текущий URL. Далее меняю параметр через parseUrl, собираю обратно unParseUrl. А вызываемым чанкам передаю весь url.

                      Нужно сменить или хостинг, или логику работы
                      1 Гб памяти, CPU 1500 МГц. Впрочем, эти ресурсы здесь погоды не делают. В основном — скорость работы с диском на VPS. У вас, похоже, дисковые операции летают на первой космической…
                        Василий Наумкин
                        05 августа 2014, 23:08
                        0
                        300 makeUrl за 0.017 сек.

                        s195.h1.simpledream.ru/manager
                        Логин		s195
                        Пароль		JQ10DUIiLenP
                        
                        Cyrax_02
                        06 августа 2014, 09:56
                        0
                        Блин. У меня в 40 раз медленнее работает. Что за хрен.
                        Ну а переходить на simpledream — не вариант. Там маловато оперативки (хотя, 384 Мб, наверное, вполне достаточно) + дисковой памяти совсем нет (нужно от 100 Гб).
                        modx.pro/hosting/3335-hosting-simple-dream-a-new-ruler-of-tariffs/

                        И вопрос. Эти тормоза зависят исключительно от ПО хостера, разделяющего ресурсы диска по VPS, или можно оптимизировать сам VPS?
                        Cyrax_02
                        06 августа 2014, 10:01
                        0
                        h.simpledream.ru/
                        Так вот в чём дело — у вас там SSD стоят. Тогда всё понятно ))
                        Василий Наумкин
                        06 августа 2014, 10:56
                        0
                        Ты серьезно думаешь, что карта сайта не загружается в оперативную память, и каждый раз дёргается HDD?
                        Cyrax_02
                        06 августа 2014, 12:05
                        0
                        Т.е. при выполнении 300 makeURL modx обращается к диску всего 3 раза (при первом вызове makeURL)?
                        Василий Наумкин
                        06 августа 2014, 12:09
                        0
                        Он вообще не обращается к диску, потому что карта ресурсов загружается MODX в любом случае при инициализации контекста.

                        Запрос будет только если id ресурса, для которого строится url, нет в этой карте. Такого обычно не бывает.
                        Cyrax_02
                        06 августа 2014, 13:56
                        0
                        Тогда откуда берётся разница в 40 раз?
                        Василий Наумкин
                        06 августа 2014, 13:58
                        +1
                        От процессора, наверное.

                        Вот, проверь.
                        Cyrax_02
                        06 августа 2014, 14:49
                        0
                        0.0018330: Created inline chunk
                        0.7903738: Total time
                        8 388 608: Memory usage
                        В 4 раза медленнее и в 2,2 раза больше оперативки.

                        300 вызовов makeURL у вас занимает 0.04 сек, у меня — 0.75 сек. Разница — в 20 раз.
                        4-х кратный тормоз объясняется процессором (согласно тесту). Но остаётся объяснить ещё 5-кратный тормоз. Из-за диска?
                        Василий Наумкин
                        06 августа 2014, 15:41
                        0
                        Да-да, из-за диска, больше же в сервере ничего нет.

                        Ни шины, ни скорости ОЗУ, ни пропускной способности, ни платформы виртуализации — только HDD.
                        Cyrax_02
                        06 августа 2014, 17:57
                        0
                        Возможная разница во всех этих параметрах уже учтена в вышеуказанном тесте и составляет 4x. Впрочем, на разных операциях (getChunk'и и makeURL'ы) эти же самые характеристики могут дать разные «разности».
    Cyrax_02
    04 августа 2014, 23:30
    0
    Всегда думал, что $_SERVER содержит в числе своих параметров всю строку запроса целиком.
    А нихрена. Нету там всей строки:
    [REDIRECT_QUERY_STRING] => q=page.html
    [REDIRECT_URL] => /page.html
    [QUERY_STRING] => q=page.html
    [REQUEST_URI] => /page.html

    Всю жизнь $_SERVER['QUERY_STRING'] использовал. А сейчас как будто на другую планету попал. зелёные человечки полезут…
      Василий Наумкин
      05 августа 2014, 16:04
      0
      <?php
      
      define('MODX_API_MODE', true);
      require 'index.php';
      echo '<pre>';print_r($_SERVER);die;
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      29