Вывод данных из БД
        Накидал сниппет для вывода нужных данных из БД. Верстку в РНР не хочется делать — долго. Добавил блок для вывода прямо в сниппете. Все работает, но появляется информация о возврате какой-то функции.
Код сниппета(укороченный)
Если выводить таким образом
Просто данных гораздо больше и при их выводе используется довольно сложная верстка и верстать вывод html тегов на php очень не хочется.
    
    
                                                                                
            Код сниппета(укороченный)
<?php
$sth = $modx->query("SELECT * FROM reg_users");
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $data) {
    $regNum = $data['regNum'];
}
?>
<div><?php echo $regNum;?></div>выводит3173значение переменной $regNum верное. А вот откуда берется return; 1 понять не могу.
return; 1
Если выводить таким образом
<?php
$sth = $modx->query("SELECT * FROM reg_users");
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $data) {
    $regNum = $data['regNum'];
}
echo '<div>' .$regNum. '</div>';
?>то все нормально.Просто данных гораздо больше и при их выводе используется довольно сложная верстка и верстать вывод html тегов на php очень не хочется.
Комментарии: 20
                Есть прямая рекомендация так не делать, потому что работать не будет. Да и закрывать php в сниппете не надо. Полагаю, что это вывод сообщения обработчика, типа return — отдано; 1 — успешно.            
                    
                Используйте getChunk.
Например:
В вызове указывайте параметры:
Ну а там уже оформляйте как угодно.
В chunk2, к примеру:
В chunk2:
                    Например:
<?php
$sth = $modx->query("SELECT * FROM reg_users");
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $data) {
    $regNums .= $modx->getChunk($tpl, array('regNum' => $data['regNum']);
}
return $modx->getChunk($tplWrapper, array('output' => $regNums));В вызове указывайте параметры:
[[SnippetName?  
    &tplWrapper=`chunk1` 
    &tpl=`chunk2`
]]Ну а там уже оформляйте как угодно.
В chunk2, к примеру:
<ul>[[+output]]</ul>В chunk2:
<li>[[+regNum]]</li>            
                Здравствуйте, Павел.
Вы можете помочь разделить нижеследующий код на сниппет и чанк/и?:
 
                    Вы можете помочь разделить нижеследующий код на сниппет и чанк/и?:
foreach($content_currency->Record as $currency) {
	$content_currency_result[0][] = '"'.(string)$currency->attributes()->Date.'"';
	$content_currency_result[1][] = str_replace(',', '.', $currency->Value);
}
	return $content_currency_result;
}На сайте я вывожу их так:<?php echo implode(', ', $currencyArr[1]); ?>
  <?php echo implode(', ', $currencyArr[0]); ?>            
                У меня тоже под результатом выходит текст return; 1 если в сниппете смешиваются html и php коды.
Пытался разделить смешанный код на сниппет и чанк, но не получается.
Павел, надеюсь, что вы и мне тоже поможете. Заранее спасибо!
                    Пытался разделить смешанный код на сниппет и чанк, но не получается.
Павел, надеюсь, что вы и мне тоже поможете. Заранее спасибо!
                У Вас нет HTML и выводить в чанк нет смысла.
Сделайте вывод прямо в сниппете:
Этого, естественно, не нужно:
                    Сделайте вывод прямо в сниппете:
<?php
$dates= array();
$values = array();
foreach($content_currency->Record as $currency) {
    $dates[] = '"'.(string)$currency->attributes()->Date.'"';
    $values[] = str_replace(',', '.', $currency->Value);
}
echo implode(', ', $dates);
echo implode(', ', $values);
return;Этого, естественно, не нужно:
<?php echo implode(', ', $currencyArr[1]); ?>
<?php echo implode(', ', $currencyArr[0]); ?>            
                Добрый день, Павел. Большое спасибо за ответ!
Дело в том, что эти данные я вывожу в графиках с помощью Apexcharts.
Код был большим. Поэтому я сокращенно написал их.
Вот как оно выглядит:
                    Дело в том, что эти данные я вывожу в графиках с помощью Apexcharts.
Код был большим. Поэтому я сокращенно написал их.
Вот как оно выглядит:
<div id="chart" style="max-width: 760px; margin: 35px auto; opacity: 0.9;">
  <div id="responsive-chart"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script>
    var options = {
  chart: {
    width: "100%",
    height: 380,
    type: "area"
  },
  plotOptions: {
    bar: {
      horizontal: true
    }
  },
  dataLabels: {
    enabled: false
  },
  fill: {
          type: 'gradient',
          gradient: {
            shadeIntensity: 1,
            inverseColors: false,
            opacityFrom: 0.5,
            opacityTo: 0,
            stops: [0, 90, 100]
          },
  series: [
    {
      name: "Курс",    
      data: [<?php echo implode(', ', $currencyArr[1]); ?>]
    }
  ],
  xaxis: {
    categories: [<?php echo implode(', ', $currencyArr[0]); ?>]
  },
  title: {
          text: 'Динамика курса доллара США',
          align: 'left'
        },
        stroke: {
          curve: 'straight'
        },
  legend: {
    position: "right",
    verticalAlign: "top",
    containerMargin: {
      left: 35,
      right: 60
    }
  },
  responsive: [
    {
      breakpoint: 1000,
      options: {
        plotOptions: {
          bar: {
            horizontal: false
          }
        },
        legend: {
          position: "bottom"
        }
      }
    }
  ]
};
var chart = new ApexCharts(
  document.querySelector("#responsive-chart"),
  options
);
chart.render();
</script>Данный html код я выводил вместе с php кодом внутри сниппета. Поэтому под графикой выводилась ошибка return; 1.            
                Тут тоже чанк не нужен. Используйте setPlaceholders:
Вызывайте сниппет где-нибудь в начале страницы, а в скрипте вставьте плейсхолдеры:
                    <?php
$dates= array();
$values = array();
foreach($content_currency->Record as $currency) {
    $dates[] = '"'.(string)$currency->attributes()->Date.'"';
    $values[] = str_replace(',', '.', $currency->Value);
}
$modx->setPlaceholders(array(
    'dates' => implode(', ', $dates),
    'values' => implode(', ', $values),
));
return;Вызывайте сниппет где-нибудь в начале страницы, а в скрипте вставьте плейсхолдеры:
//..........
series: [
    {
      name: "Курс",    
      data: [ [[+values]] ]
    }
  ],
  xaxis: {
    categories: [ [[+dates]]  ]
  },
//..........            
                Что-то 
                    [[+value]] и [[+dates]] пустыми отображаются.            
                Не знаю, что сделал, но теперь уже работает.            
                    
                Павел, большое вам спасибо за помощь! Все отлично работает.            
                    
                Павел, а как быть с выводом данных в таблицу? В обычном php файле, следующий код работает, но используя в сниппете выходит ошибка return;1.
А необходимо чтобы данные распределились в отдельные tr td.
Предполагаю, что тут уже без чанка/ов не обойтись, верно?
Если да, то как это реализовать? Заранее спасибо!
                    <?php
function get_currency_td($currency_code = 'R01235') {
$date_start = date('d/m/Y', strtotime('-30 days')); // Дата начала выборки
	$date = date('d/m/Y'); // Текущая дата (используется для кэша и для конца выборки)
$cache_time_out = 86400; // Время жизни кэша в секундах
$file_currency_cache = './currency.xml'; // Файл кэша
if(!is_file($file_currency_cache) || filemtime($file_currency_cache) < (time() - $cache_time_out)) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.cbr.ru/scripts/XML_dynamic.asp?date_req1='.$date_start.'&date_req2='.$date.'&VAL_NM_RQ='.$currency_code);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$out = curl_exec($ch);
curl_close($ch);
file_put_contents($file_currency_cache, $out);
}
$content_currency = simplexml_load_file($file_currency_cache);
$content_currency_result = ''; // Переменная для объединения всех дней в одну группу
foreach($content_currency->Record as $currency) {
$content_currency_result .= '<tr><td>'.$currency->attributes()->Date.' </td><td> '.$currency->Value.'</td><td></td></tr>';
}
return $content_currency_result;
}
?>
<div class="currency-exchange">
<div class="ce-title">Таблица изменений курса доллара США за 30 дней</div>
<table class="table table-condensed ce-table">
<thead>
<tr>
<td>Дата</td>
<td>Курс рублей за 1 usd</td>
<td>Изменение</td>
</tr>
</thead>
<tbody>
<?php echo get_currency_td('R01235'); ?>
</tbody>
</table>
</div>Оставив только php код в сниппете и переносив html код в шаблон, пробовал использовать setPlaceholders, но с таблицей не получается. Данные отображаются внутри одного <tr>
<td></td>
<td></td>
<td></td>
</tr>Вот скриншот: https://skr.sh/sFCZaUMux90?aА необходимо чтобы данные распределились в отдельные tr td.
Предполагаю, что тут уже без чанка/ов не обойтись, верно?
Если да, то как это реализовать? Заранее спасибо!
                Поскольку тут уже HTML, то через getChunk.
Сниппет:
Вызов:
Чанк chunk_wrapper:
Чанк chunk_item:
                    Сниппет:
<?php
$out = '';
$date_start = date('d/m/Y', strtotime('-30 days')); // Дата начала выборки
$date = date('d/m/Y'); // Текущая дата (используется для кэша и для конца выборки)
$cache_time_out = 86400; // Время жизни кэша в секундах
$file_currency_cache = './currency.xml'; // Файл кэша
if(!is_file($file_currency_cache) || filemtime($file_currency_cache) < (time() - $cache_time_out)) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://www.cbr.ru/scripts/XML_dynamic.asp?date_req1='.$date_start.'&date_req2='.$date.'&VAL_NM_RQ='.$currency_code);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    $out = curl_exec($ch);
    curl_close($ch);
    file_put_contents($file_currency_cache, $out);
}
$content_currency = simplexml_load_file($file_currency_cache);
$content_currency_result = ''; // Переменная для объединения всех дней в одну группу
foreach($content_currency->Record as $currency) {
    $items .= $modx->getChunk($tpl, array(
        'date' => $currency->attributes()->Date,
        'value' => $currency->Value,
    ))
}	
if($items != '') $out = $modx->getChunk($tplWrapper, array('items' => $items));
return $out;Вызов:
[[snippetName?
    &tplWrapper=`chunk_wrapper`
    &tpl=`chunk_item`
]]Чанк chunk_wrapper:
<div class="currency-exchange">
    <div class="ce-title">Таблица изменений курса доллара США за 30 дней</div>
    <table class="table table-condensed ce-table">
        <thead>
            <tr>
                <td>Дата</td>
                <td>Курс рублей за 1 usd</td>
                <td>Изменение</td>
            </tr>
        </thead>
        <tbody>
            [[+items]]
        </tbody>
    </table>
</div>Чанк chunk_item:
<tr>
    <td>[[+date]]</td>
    <td>[[+value]]</td>
    <td></td>
</tr>            
                Павел, добрый день! Спасибо большое за подробный ответ.
Без ; после:
Вставляю ; после двух скобок ));, ошибка пропадает.
Но таблица отображается. Но уже с пустыми [[+date]] и [[+value]]. Скриншот: https://skr.sh/sFDGc49PTvC?a.
P.S В сниппет я также добавил строку:
                    Без ; после:
foreach($content_currency->Record as $currency) {
    $items .= $modx->getChunk($tpl, array(
        'date' => $currency->attributes()->Date,
        'value' => $currency->Value,
    ))на сайте выдает ошибку 500.Вставляю ; после двух скобок ));, ошибка пропадает.
Но таблица отображается. Но уже с пустыми [[+date]] и [[+value]]. Скриншот: https://skr.sh/sFDGc49PTvC?a.
P.S В сниппет я также добавил строку:
$currency_code = 'R01235';Думал, что может из-за этого таблица пустая. Но, оказывается не из-за этого.            
                Да, добавьте точку с запятой, я опечатался.
Если Вы используете функцию, то нужно в ней объявить глобальную переменную $modx:
Но если у Вас задача вывести этим сниппетом только курсы доллара, функция не нужна, но надо непосредственно указать код валюты (в 9 строке):
                    Если Вы используете функцию, то нужно в ней объявить глобальную переменную $modx:
function get_currency_td($currency_code = 'R01235') {
    global $modx;
    $out = '';
    $date_start = date('d/m/Y', strtotime('-30 days')); // Дата начала выборки
    $date = date('d/m/Y'); // Текущая дата (используется для кэша и для конца выборки)
    $cache_time_out = 86400; // Время жизни кэша в секундах
    $file_currency_cache = './currency.xml'; // Файл кэша
    if(!is_file($file_currency_cache) || filemtime($file_currency_cache) < (time() - $cache_time_out)) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://www.cbr.ru/scripts/XML_dynamic.asp?date_req1='.$date_start.'&date_req2='.$date.'&VAL_NM_RQ='.$currency_code);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        $out = curl_exec($ch);
        curl_close($ch);
        file_put_contents($file_currency_cache, $out);
    }
    $content_currency = simplexml_load_file($file_currency_cache);
    $content_currency_result = ''; // Переменная для объединения всех дней в одну группу
    
    foreach($content_currency->Record as $currency) {
        $items .= $modx->getChunk($tpl, array(
            'date' => $currency->attributes()->Date,
            'value' => $currency->Value,
        ));
    }	
    if($items != '') $out = $modx->getChunk($tplWrapper, array('items' => $items));
    return $out;
}Но потом, естественно, в сниппете где-то нужно эту функцию вызывать.Но если у Вас задача вывести этим сниппетом только курсы доллара, функция не нужна, но надо непосредственно указать код валюты (в 9 строке):
<?php
$out = '';
$date_start = date('d/m/Y', strtotime('-30 days')); // Дата начала выборки
$date = date('d/m/Y'); // Текущая дата (используется для кэша и для конца выборки)
$cache_time_out = 86400; // Время жизни кэша в секундах
$file_currency_cache = './currency.xml'; // Файл кэша
if(!is_file($file_currency_cache) || filemtime($file_currency_cache) < (time() - $cache_time_out)) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://www.cbr.ru/scripts/XML_dynamic.asp?date_req1='.$date_start.'&date_req2='.$date.'&VAL_NM_RQ=R01235');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    $out = curl_exec($ch);
    curl_close($ch);
    file_put_contents($file_currency_cache, $out);
}
$content_currency = simplexml_load_file($file_currency_cache);
$content_currency_result = ''; // Переменная для объединения всех дней в одну группу
foreach($content_currency->Record as $currency) {
    $items .= $modx->getChunk($tpl, array(
        'date' => $currency->attributes()->Date,
        'value' => $currency->Value,
    ));
}	
if($items != '') $out = $modx->getChunk($tplWrapper, array('items' => $items));
return $out;            
                Да, задача вывести этим сниппетом только курсы доллара по дням.
Поэтому использовал второй вариант без функции.
Но не могу понять, почему-то [[+date]] и [[+value]] возвращаются пустыми.
                    Поэтому использовал второй вариант без функции.
Но не могу понять, почему-то [[+date]] и [[+value]] возвращаются пустыми.
                К строке приведите:
                    // .............
foreach($content_currency->Record as $currency) {
    $items .= $modx->getChunk($tpl, array(
        'date' => (string)$currency->attributes()->Date,
        'value' => (string)$currency->Value,
    ));
}
// .............            
                Павел, огромное вам спасибо! Задача решена.            
                    
                Ну или можно попробовать поиграть в прятки с обработчиком и открыть в конце сниппета пустой php, например:
                    <?php
$sth = $modx->query("SELECT * FROM reg_users");
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $data) {
    $regNum = $data['regNum'];
}
?>
<div><?php echo $regNum;?></div>
<?phpесли хочется костылей :D            
                Не, костылей не надо. И так хромаю на обе ноги))) Рецепт от Павла Романова помог. Спасибо всем!            
                    <?php
$sth = $modx->query("SELECT * FROM reg_users");
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $data) {
    $regNum = $data['regNum'];
}
?>
<div><?php echo $regNum;?></div>
<?php return ''; ?>            
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.