ドロップダウンリスト(セレクトボックス)とデータベースを連携する方法について紹介します。いちいち手動でリストを作る必要がなく、データベースが更新されればリストの内容も自動更新されるようになります。

管理画面(商品登録)をカスタマイズし、メーカーIDをドロップダウンリストで選択→登録できるようにしました。「dtb_maker」という新しいテーブルを新規作成し、そこに保存されているメーカー名をリストとして表示させています。
- 「dtb_product」テーブルの拡張
-
こちらの記事では、「maker_id」ではなく「production_area」を追加しているので、ProductTrait.phpを以下に修正してください。
修正後の ProductTrait.php はこちら
<?php namespace Customize\Entity; use Doctrine\ORM\Mapping as ORM; use Eccube\Annotation\EntityExtension; /** * 拡張したいエンティティ(ここでは「Product」エンティティ)を指定。 * * @EntityExtension("Eccube\Entity\Product") */ trait ProductTrait { /** * メーカーID * * @var integer|null * * @ORM\Column(name="maker_id", type="integer", nullable=true) */ private $maker_id = null; /** * メーカーIDを設定 * * @param integer|null $maker_id * * @return $this */ public function setMakerId(?int $maker_id): self { $this->maker_id = $maker_id; return $this; } /** * メーカーIDを取得 * * @return integer|null */ public function getMakerId(): ?int { return $this->maker_id; } }
- 「dtb_maker」テーブルの新規作成
-
テーブル追加後は、実装確認用に適当データ(レコード)を追加しておいてください。
- 商品登録画面のフォームタイプ「ProductTypeExtension.php」の作成とtwigテンプレート「product.twig」の修正
-
こちらの記事では、「maker_id」ではなく「production_area」を追加しているので、product.twigを以下に修正してください。
修正後の product.twig はこちら
{# メーカーの登録フォーム #} <div class="row"> <div class="col-3"> <div class="d-inline-block"> <span>メーカーID</span> </div> </div> <div class="col mb-2"> <div> {{ form_widget(form.maker_id) }} {{ form_errors(form.maker_id) }} </div> </div> </div>
デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。
カスタマイズ後は、デバッグモードの解除を忘れないように。
ドロップダウンリストを表示するフォームを作成する
まずはドロップダウンリストを表示するためのフォームを作成します。フォームタイプの作成については こちらの記事 で解説していますが、追加したいフォームタイプに以下コードを記述します。
$builder
->add('maker_id', ChoiceType::class, [
'choices' =>
[
'SampleCorp' => 1,
'Noveblo Ltd.' => 2,
'TEST Company' => 3,
],
'required' => false,
'placeholder' => '選択してください'
]);
本記事の例では、こちらの記事で作成した「ProductTypeExtension.php」のadd
メソッドを上記コードに修正しています。なお、ChoiceTypeを使うにはuse
でChoiceType
クラスを読み込んでおく必要があるので、以下コードも忘れないようにしましょう。
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
ProductTypeExtension.php 全コード
<?php
namespace Customize\Form\Extension\Admin;
use Eccube\Form\Type\Admin\ProductType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
class ProductTypeExtension extends AbstractTypeExtension
{
// どのフォームを拡張するかを宣言(EC-CUBEのバージョンによって記述方法が異なる)
public static function getExtendedTypes(): iterable
{
yield ProductType::class; // ProductTypeを拡張
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('maker_id', ChoiceType::class, [
'choices' =>
[
'SampleCorp' => 1,
'Noveblo Ltd.' => 2,
'TEST Company' => 3,
],
'required' => false,
'placeholder' => '選択してください'
]);
}
}
ただこのコードを見てわかるとおり、リストの内容は直接add
メソッド内に記述されています。
次は、このリストをデータベースから取得できるようにします。
リストの内容をデータベースから取得する
データベースからデータを取得するには、Repositoryという機能を使います。
本記事の「dtb_maker」のような新規に作成したテーブルにはRepositoryがないので、まずはRepositoryを作成する必要があります。(すでに作成済の場合、以下はスキップしてください。)
Repositoryの新規作成
以下コードを記述した「MakerRepository.php」を作成し、「app/Customize/Repository」下に保存します。
EC-CUBEのバージョンによってコードが異なります。(4.2以降ではResistoryInterface
が使えず、ManagerRegistry
を使います。)
【EC-CUBE 4.0 / 4.1】のRepositoryファイルはこちら
<?php
namespace Customize\Repository;
use Customize\Entity\Maker;
use Eccube\Repository\AbstractRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
* MakerRepository
*/
class MakerRepository extends AbstractRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Maker::class);
}
}
【EC-CUBE 4.2以降】のRepositoryファイルはこちら
<?php
namespace Customize\Repository;
use Customize\Entity\Maker;
use Eccube\Repository\AbstractRepository;
use Doctrine\Persistence\ManagerRegistry as RegistryInterface;
/**
* MakerRepository
*/
class MakerRepository extends AbstractRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Maker::class);
}
}
Repositoryの作成と活用法については、以下記事も参考にしてみてください。

フォームタイプでRepositoryを使い、リストデータを取得する
Repositoryを用意できたら、フォームタイプを以下の通り修正していきます。
本記事では「ProductTypeExtension.php」を修正しています。
useでRepositoryを読み込む
使いたいRepositoryをuse
で読み込みます。
use Customize\Repository\MakerRepository;
本記事では、先程作成したMakerRepository
を読み込みます。
Repositoryの初期化設定
ProductTypeExtension
クラス内で、読み込んだRepositoryを初期化します。
class ProductTypeExtension extends AbstractTypeExtension
{
/**
* @var MakerRepository
*/
protected $makerRepository;
/**
* @param MakerRepository $makerRepository
*/
public function __construct(MakerRepository $makerRepository)
{
$this->makerRepository = $makerRepository;
}
なお、ステップ1とステップ2については以下記事にて解説しています。

Repositoryを使ってリストデータを取得する
RepositoryのfindAll
()メソッドを使って「dtb_maker」の全レコードを取得し、配列$choices
に「メーカー名 => ID」となるようデータを格納します。
$makers = $this->makerRepository->findAll();
$choices = array_combine(
array_map(fn($maker) => $maker->getName(), $makers),
array_map(fn($maker) => $maker->getId(), $makers)
);
なお、findAll()
などRepositoryのメソッドについては以下記事にて解説しています。

取得したリストデータをaddメソッドにセットする
リストデータを格納した$choices
をadd
メソッドの'choices'
にセットし、完成です。
$builder
->add('maker_id', ChoiceType::class, [
'choices' => $choices,
'required' => false,
'placeholder' => '選択してください'
]);
以上でカスタマイズは終了です。
上述のとおりフォームタイプの修正点が多く、コードの記述ミスや記述場所を間違いやすいです。
以下に「ProductTypeExtension.php」の全コードを載せておくので、参考にしてください。
ProductTypeExtension.php(修正後)
<?php
namespace Customize\Form\Extension\Admin;
use Eccube\Form\Type\Admin\ProductType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Customize\Repository\MakerRepository;
class ProductTypeExtension extends AbstractTypeExtension
{
/**
* @var MakerRepository
*/
protected $makerRepository;
/**
* @param MakerRepository $makerRepository
*/
public function __construct(MakerRepository $makerRepository)
{
$this->makerRepository = $makerRepository;
}
/**
* どのフォームを拡張するかを宣言(EC-CUBEのバージョンによって記述方法が異なる)
*
* @return iterable
*/
public static function getExtendedTypes(): iterable
{
return [ProductType::class]; // ProductTypeを拡張
}
/**
* フォームにメーカーIDの選択肢を追加
*
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$makers = $this->makerRepository->findAll();
$choices = array_combine(
array_map(fn($maker) => $maker->getName(), $makers),
array_map(fn($maker) => $maker->getId(), $makers)
);
$builder
->add('maker_id', ChoiceType::class, [
'choices' => $choices,
'required' => false,
'placeholder' => '選択してください',
]);
}
}
まとめ
以上、ドロップダウンリスト(セレクトボックス)の選択肢をデータベースから取得する方法について紹介しました。
本記事で取り上げた実装例は、データベース拡張やRepository、FormTypeなど、Symfonyの基本的な機能が一通り理解できていないと難しいと思います。ぜひ他の記事を参考に、トライしてみてください!
