Я пишу код Perl, и я совершенно нуб (специализируюсь на PHP и JS). Я получаю некоторые данные из запроса API JSON, и я хочу сослаться на данные и создать некоторые параметры HTML для поля выбора. Но я просто не могу понять, как ссылаться на значения из ответа JSON.
#!/bin/false
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;
use vars qw(@parameters $new $mode $metainfo);
use Data::Dumper qw(Dumper);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my @pagetypes = _getPagetypes();
if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
return "";
}
my $html = "";
foreach (@pagetypes) {
my $pagetype = $_;
return Dumper @pagetypes;
$html .= sprintf(
'<option value = "%s">%s</option>',
$pagetype->{"identifier"},
encode_utf8($pagetype->{"label"}),
);
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getPagetypes
{
my $url = sprintf(
"%s/page-types/",
$ENV{'URL'}
);
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
my $header = HTTP::Request->new(GET => $url);
my $request = HTTP::Request->new('GET', $url, $header);
my $response = $ua->request($request);
my @data = decode_json($response->content);
my @pagetypes = @data[0]->{'pageTypes'};
return @pagetypes;
}
Там, где написано return Dumper $pagetypes;
, записывается следующий вывод:
$VAR1 = [
{
'label' => 'Projektsteckbrief',
'identifier' => 'pagetype-profile'
}
];
Я пробовал $pagetype->{"label"}
и $pagetypes[0]->{"label"}
и многое другое... но я просто не знаю, как получить там метку и идентификатор.
Обновить:
Я попытался реализовать типы страниц вручную, и это отлично работает с методом main()
(без вызова дампера):
sub _getPagetypes
{
my @pagetypes = (
{
identifier => "pagetype-profile",
label => "Projektsteckbrief",
},
);
return @pagetypes;
}
ОБНОВЛЕНИЕ 2:
Итак, у меня возникла новая проблема... она еще не работает полностью, но ответ Bl00D4NGEL в любом случае очень помог!
Итак, мой код сейчас выглядит так:
#!/bin/false
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;
use Project::Util::Api;
use vars qw(@parameters $new $mode $metainfo);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my @pagetypes = _getPagetypes();
if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
return "";
}
my $html = "";
foreach my $pagetype (@pagetypes) {
# selection will be automatically set by Imperia
$html .= sprintf(
'<option value = "%s">%s</option>',
$pagetype->[0]->{"identifier"},
encode_utf8($pagetype->[0]->{"label"}),
);
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getPagetypes
{
my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");
my @pagetypes = $response->{"pageTypes"};
return @pagetypes;
}
$new = main();
Проблема в том, что теперь отображается только один элемент.
Итак, $pagetype
в моем цикле foreach выглядит так, как будто это все еще массив со всеми элементами внутри, а затем $pagetype->[0]
дает мне только первый элемент из массива.
Когда я использую for
вместо foreach
вот так:
for ( $a = 0 ; $a <= 10 ; $a++ ) {
$html .= sprintf(
'<option value = "%s">%s</option>',
@pagetypes[0]->[$a]->{"id"},
encode_utf8(@pagetypes[0]->[$a]->{"label"}),
);
}
Я получаю 10 элементов из 200, но никак не могу понять, как получить длину массива @pagetypes
.
Я пробовал следующее:
# 500 Server error (because of long loading?)
for ( $a = 0 ; $a <= @pagetypes[0] ; $a++ ) {
my $pagetypesLength = @pagetypes;
# Only 2 items are displayed
for ( $a = 0 ; $a <= @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= $pagetypesLength ; $a++ ) {
for ( $a = 0 ; $a <= scalar @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= length @pagetypes ; $a++ ) {
ОБНОВЛЕНИЕ 3 (НАКОНЕЦ-ТО РАБОТАЕТ):
Итак, наконец, мне удалось заставить его работать. Окончательный код следующий:
#!/bin/false
use strict;
use warnings;
use Encode;
use Project::Util::Api;
use vars qw(@parameters $new $mode $metainfo);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my $items = _getData();
if (0 == scalar @$items) {
return "";
}
my $html = "";
# $#{$items} is last index of array reference $items
for (my $i = 0 ; $i <= $#{$items} ; $i++) {
if (defined $items->[$i]->{"id"}) {
# option selection will be automatically set by Imperia
$html .= sprintf(
'<option value = "%s">%s</option>',
$items->[$i]->{"identifier"},
encode_utf8($items->[$i]->{"label"}),
);
}
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getData
{
my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");
return $response->{"pageTypes"};
}
$new = main();
Ты прав, извини. Я попытался получить доступ к переменной с помощью $
и не отменил ее. Я обновил фрагмент кода и добавил другую информацию.
Похоже, что переменная $pagetype на самом деле является ссылкой на массив (по крайней мере, глядя на Dumper, это выглядит так) Итак, что, вероятно, должно решить эту проблему, так это:
my $pagetype = $_;
$html .= sprintf(
'<option value = "%s">%s</option>',
$pagetype->[0]->{"identifier"},
encode_utf8($pagetype->{"label"}),
);
Слава богу, это работает! Я думаю, что вы обращаетесь к этому массиву с помощью $pagetype[0]
. Я предполагаю, что ->
нужно использовать, потому что это ссылка?
Да, конечно. Вы должны проверить эту статью о Perl Maven: perlmaven.com/array-references-in-perl
большое спасибо! Могу я попросить вас проверить ОБНОВЛЕНИЕ 2 в моем первоначальном вопросе? С вашим комментарием я получаю только первый элемент массива. Большое спасибо!
Похоже, вы неправильно обращаетесь к @pagetypes. если вы хотите получить доступ к массиву или хеш-элементу, вам нужно ввести $variable[0] или $variable{'key'} для доступа к нему. Вы пытались получить доступ к переменной, используя @pagetypes[0]->[$a]->{"id"}, что неверно, поэтому возникла синтаксическая ошибка.
нет, @pagetypes[0]->[$a]->{"id"} работает нормально. Проблема в том, что я не знаю, как получить правильный код для длины массива в цикле for. и с foreach единственный $pagetype всегда является полным массивом @pagetypes в дампере :(
чтобы получить длину массива в perl, используйте scalar(@array), но если я правильно понимаю ваш сценарий, массив @pagetype имеет только один элемент (в индексе 0), и там есть несколько значений, я прав с этим ? Если это так, вам может понадобиться сделать что-то вроде my @values = @{$pagetypes[0]}
, а затем выполнить for my $value (@values) { ... }
для перебора элементов.
В вашем вопросе обсуждается
return Dumper $pagetypes;
, но код не показывает скалярную переменную$pagetypes
, он показывает массив@pagetypes
. Поэтому мы можем только догадываться, что вы на самом деле делаете, чтобы получить дамп, который вы показали. Пожалуйста, опубликуйте фактический фрагмент кода, который создает дамп, который вы видите.