ラベル 学習 の投稿を表示しています。 すべての投稿を表示
ラベル 学習 の投稿を表示しています。 すべての投稿を表示

PHP:プロになるためのPHPプログラミング入門 サンプル環境構築(2)

公開:2026.05.15(金) 01:17

プロになるためのPHPプログラミング入門 サンプル環境構築

プロになるためのPHPプログラミング入門 サンプル環境構築」の続き。

1. Compose環境を作る
まずは PHP Composer環境を作る。
→「PHP:Compose環境を作る

実行結果:
xxxxxxxx@yyyy:~/docker/php$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED      STATUS          PORTS                                                    NAMES
3d8258bc2177   php:8.3-apache          "docker-php-entrypoi…"   2 days ago   Up 11 minutes   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp                  php-php-1
d094e1650051   mysql:8.0               "docker-entrypoint.s…"   2 days ago   Up 11 minutes   0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp   php-db-1
b60aebf325a6   phpmyadmin/phpmyadmin   "/docker-entrypoint.…"   2 days ago   Up 11 minutes   0.0.0.0:8081->80/tcp, [::]:8081->80/tcp                  php-phpmyadmin-1
xxxxxxxx@yyyy:~/docker/php$ docker exec -it 3d8258bc2177 /bin/bash
root@3d8258bc2177:/var/www/html# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
Xdebug: [Log Files] File '/tmp/xdebug.log' could not be opened.
root@3d8258bc2177:/var/www/html# php -r "if (hash_file('sha384', 'composer-setup.php') === 'c8b085408188070d5f52bcfe4ecfbee5f727afa458b2573b8eaaf77b3419b0bf2768dc67c86944da1544f06fa544fd47') { echo 'Installer verified'.PHP_EOL; } else { echo 'Installer corrupt'.PHP_EOL; unlink('composer-setup.php'); exit(1); }"
Xdebug: [Log Files] File '/tmp/xdebug.log' could not be opened.
Installer verified
root@3d8258bc2177:/var/www/html# php composer-setup.php
Xdebug: [Log Files] File '/tmp/xdebug.log' could not be opened.
All settings correct for using Composer
Downloading...

Composer (version 2.9.8) successfully installed to: /var/www/html/composer.phar
Use it: php composer.phar

root@3d8258bc2177:/var/www/html# php -r "unlink('composer-setup.php');"
Xdebug: [Log Files] File '/tmp/xdebug.log' could not be opened.
root@3d8258bc2177:/var/www/html# mv composer.phar /usr/local/bin/composer

2. Twigインストール
サンプルのテンプレートエンジンは HTML_Templafe_Flexy というのを使っているが、PHP8.3環境だとうまく動かないため Twig を使うことにする。
→「PHP:Twigのインストール

2-1. Twigが必要なコンポーネントのインストール
実行結果:
root@3d8258bc2177:/var/www/prophp_sample# apt-get update [ \
apt-get install -y \
libzip-dev \
git \
unzip \
zip \
&& docker-php-ext-install zip
Hit:1 http://deb.debian.org/debian trixie InRelease
Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9671 kB]
Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [5412 B]
Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [161 kB]
Fetched 9928 kB in 1s (12.2 MB/s)
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  git-man less libcbor0.10 libcurl3t64-gnutls libedit2 liberror-perl libfido2-1 libngtcp2-16 libngtcp2-crypto-gnutls8
  libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxext6 libxmuu1 libzip5 openssh-client xauth zipcmp zipmerge
  ziptool zlib1g-dev
Suggested packages:
  gettext-base git-doc git-email git-gui gitk gitweb git-cvs git-mediawiki git-svn keychain libpam-ssh monkeysphere
  ssh-askpass
The following NEW packages will be installed:
  git git-man less libcbor0.10 libcurl3t64-gnutls libedit2 liberror-perl libfido2-1 libngtcp2-16
  libngtcp2-crypto-gnutls8 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxext6 libxmuu1 libzip-dev libzip5
  openssh-client unzip xauth zip zipcmp zipmerge ziptool zlib1g-dev
0 upgraded, 27 newly installed, 0 to remove and 6 not upgraded.
Need to get 16.1 MB of archives.
After this operation, 67.3 MB of additional disk space will be used.
Get:1 http://deb.debian.org/debian trixie/main amd64 less amd64 668-1 [161 kB]
Get:2 http://deb.debian.org/debian trixie/main amd64 libedit2 amd64 3.1-20250104-1 [93.8 kB]
Get:3 http://deb.debian.org/debian trixie/main amd64 libcbor0.10 amd64 0.10.2-2 [28.3 kB]
Get:4 http://deb.debian.org/debian trixie/main amd64 libfido2-1 amd64 1.15.0-1+b1 [78.7 kB]
Get:5 http://deb.debian.org/debian-security trixie-security/main amd64 openssh-client amd64 1:10.0p1-7+deb13u2 [986 kB]
Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 libngtcp2-16 amd64 1.11.0-1+deb13u1 [132 kB]
Get:7 http://deb.debian.org/debian-security trixie-security/main amd64 libngtcp2-crypto-gnutls8 amd64 1.11.0-1+deb13u1 [29.5 kB]
Get:8 http://deb.debian.org/debian trixie/main amd64 libcurl3t64-gnutls amd64 8.14.1-2+deb13u2 [383 kB]
Get:9 http://deb.debian.org/debian trixie/main amd64 liberror-perl all 0.17030-1 [26.9 kB]
Get:10 http://deb.debian.org/debian trixie/main amd64 git-man all 1:2.47.3-0+deb13u1 [2205 kB]
Get:11 http://deb.debian.org/debian trixie/main amd64 git amd64 1:2.47.3-0+deb13u1 [8862 kB]
Get:12 http://deb.debian.org/debian trixie/main amd64 libxau6 amd64 1:1.0.11-1 [20.4 kB]
Get:13 http://deb.debian.org/debian trixie/main amd64 libxdmcp6 amd64 1:1.1.5-1 [27.8 kB]
Get:14 http://deb.debian.org/debian trixie/main amd64 libxcb1 amd64 1.17.0-2+b1 [144 kB]
Get:15 http://deb.debian.org/debian trixie/main amd64 libx11-data all 2:1.8.12-1 [343 kB]
Get:16 http://deb.debian.org/debian trixie/main amd64 libx11-6 amd64 2:1.8.12-1 [815 kB]
Get:17 http://deb.debian.org/debian trixie/main amd64 libxext6 amd64 2:1.3.4-1+b3 [50.4 kB]
Get:18 http://deb.debian.org/debian trixie/main amd64 libxmuu1 amd64 2:1.1.3-3+b4 [21.9 kB]
Get:19 http://deb.debian.org/debian trixie/main amd64 libzip5 amd64 1.11.3-2 [62.6 kB]
Get:20 http://deb.debian.org/debian trixie/main amd64 zipcmp amd64 1.11.3-2 [19.8 kB]
Get:21 http://deb.debian.org/debian trixie/main amd64 zipmerge amd64 1.11.3-2 [14.5 kB]
Get:22 http://deb.debian.org/debian trixie/main amd64 ziptool amd64 1.11.3-2 [22.6 kB]
Get:23 http://deb.debian.org/debian trixie/main amd64 zlib1g-dev amd64 1:1.3.dfsg+really1.3.1-1+b1 [920 kB]
Get:24 http://deb.debian.org/debian trixie/main amd64 libzip-dev amd64 1.11.3-2 [181 kB]
Get:25 http://deb.debian.org/debian trixie/main amd64 unzip amd64 6.0-29 [173 kB]
Get:26 http://deb.debian.org/debian trixie/main amd64 xauth amd64 1:1.1.2-1.1 [35.9 kB]
Get:27 http://deb.debian.org/debian trixie/main amd64 zip amd64 3.0-15 [235 kB]
Fetched 16.1 MB in 1s (29.3 MB/s)
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 79, <STDIN> line 27.)
debconf: falling back to frontend: Readline
Selecting previously unselected package less.
(Reading database ... 15584 files and directories currently installed.)
Preparing to unpack .../00-less_668-1_amd64.deb ...
Unpacking less (668-1) ...
Selecting previously unselected package libedit2:amd64.
Preparing to unpack .../01-libedit2_3.1-20250104-1_amd64.deb ...
Unpacking libedit2:amd64 (3.1-20250104-1) ...
Selecting previously unselected package libcbor0.10:amd64.
Preparing to unpack .../02-libcbor0.10_0.10.2-2_amd64.deb ...
Unpacking libcbor0.10:amd64 (0.10.2-2) ...
Selecting previously unselected package libfido2-1:amd64.
Preparing to unpack .../03-libfido2-1_1.15.0-1+b1_amd64.deb ...
Unpacking libfido2-1:amd64 (1.15.0-1+b1) ...
Selecting previously unselected package openssh-client.
Preparing to unpack .../04-openssh-client_1%3a10.0p1-7+deb13u2_amd64.deb ...
Unpacking openssh-client (1:10.0p1-7+deb13u2) ...
Selecting previously unselected package libngtcp2-16:amd64.
Preparing to unpack .../05-libngtcp2-16_1.11.0-1+deb13u1_amd64.deb ...
Unpacking libngtcp2-16:amd64 (1.11.0-1+deb13u1) ...
Selecting previously unselected package libngtcp2-crypto-gnutls8:amd64.
Preparing to unpack .../06-libngtcp2-crypto-gnutls8_1.11.0-1+deb13u1_amd64.deb ...
Unpacking libngtcp2-crypto-gnutls8:amd64 (1.11.0-1+deb13u1) ...
Selecting previously unselected package libcurl3t64-gnutls:amd64.
Preparing to unpack .../07-libcurl3t64-gnutls_8.14.1-2+deb13u2_amd64.deb ...
Unpacking libcurl3t64-gnutls:amd64 (8.14.1-2+deb13u2) ...
Selecting previously unselected package liberror-perl.
Preparing to unpack .../08-liberror-perl_0.17030-1_all.deb ...
Unpacking liberror-perl (0.17030-1) ...
Selecting previously unselected package git-man.
Preparing to unpack .../09-git-man_1%3a2.47.3-0+deb13u1_all.deb ...
Unpacking git-man (1:2.47.3-0+deb13u1) ...
Selecting previously unselected package git.
Preparing to unpack .../10-git_1%3a2.47.3-0+deb13u1_amd64.deb ...
Unpacking git (1:2.47.3-0+deb13u1) ...
Selecting previously unselected package libxau6:amd64.
Preparing to unpack .../11-libxau6_1%3a1.0.11-1_amd64.deb ...
Unpacking libxau6:amd64 (1:1.0.11-1) ...
Selecting previously unselected package libxdmcp6:amd64.
Preparing to unpack .../12-libxdmcp6_1%3a1.1.5-1_amd64.deb ...
Unpacking libxdmcp6:amd64 (1:1.1.5-1) ...
Selecting previously unselected package libxcb1:amd64.
Preparing to unpack .../13-libxcb1_1.17.0-2+b1_amd64.deb ...
Unpacking libxcb1:amd64 (1.17.0-2+b1) ...
Selecting previously unselected package libx11-data.
Preparing to unpack .../14-libx11-data_2%3a1.8.12-1_all.deb ...
Unpacking libx11-data (2:1.8.12-1) ...
Selecting previously unselected package libx11-6:amd64.
Preparing to unpack .../15-libx11-6_2%3a1.8.12-1_amd64.deb ...
Unpacking libx11-6:amd64 (2:1.8.12-1) ...
Selecting previously unselected package libxext6:amd64.
Preparing to unpack .../16-libxext6_2%3a1.3.4-1+b3_amd64.deb ...
Unpacking libxext6:amd64 (2:1.3.4-1+b3) ...
Selecting previously unselected package libxmuu1:amd64.
Preparing to unpack .../17-libxmuu1_2%3a1.1.3-3+b4_amd64.deb ...
Unpacking libxmuu1:amd64 (2:1.1.3-3+b4) ...
Selecting previously unselected package libzip5:amd64.
Preparing to unpack .../18-libzip5_1.11.3-2_amd64.deb ...
Unpacking libzip5:amd64 (1.11.3-2) ...
Selecting previously unselected package zipcmp.
Preparing to unpack .../19-zipcmp_1.11.3-2_amd64.deb ...
Unpacking zipcmp (1.11.3-2) ...
Selecting previously unselected package zipmerge.
Preparing to unpack .../20-zipmerge_1.11.3-2_amd64.deb ...
Unpacking zipmerge (1.11.3-2) ...
Selecting previously unselected package ziptool.
Preparing to unpack .../21-ziptool_1.11.3-2_amd64.deb ...
Unpacking ziptool (1.11.3-2) ...
Selecting previously unselected package zlib1g-dev:amd64.
Preparing to unpack .../22-zlib1g-dev_1%3a1.3.dfsg+really1.3.1-1+b1_amd64.deb ...
Unpacking zlib1g-dev:amd64 (1:1.3.dfsg+really1.3.1-1+b1) ...
Selecting previously unselected package libzip-dev:amd64.
Preparing to unpack .../23-libzip-dev_1.11.3-2_amd64.deb ...
Unpacking libzip-dev:amd64 (1.11.3-2) ...
Selecting previously unselected package unzip.
Preparing to unpack .../24-unzip_6.0-29_amd64.deb ...
Unpacking unzip (6.0-29) ...
Selecting previously unselected package xauth.
Preparing to unpack .../25-xauth_1%3a1.1.2-1.1_amd64.deb ...
Unpacking xauth (1:1.1.2-1.1) ...
Selecting previously unselected package zip.
Preparing to unpack .../26-zip_3.0-15_amd64.deb ...
Unpacking zip (3.0-15) ...
Setting up libxau6:amd64 (1:1.0.11-1) ...
Setting up libxdmcp6:amd64 (1:1.1.5-1) ...
Setting up libxcb1:amd64 (1.17.0-2+b1) ...
Setting up libzip5:amd64 (1.11.3-2) ...
Setting up libcbor0.10:amd64 (0.10.2-2) ...
Setting up unzip (6.0-29) ...
Setting up libedit2:amd64 (3.1-20250104-1) ...
Setting up less (668-1) ...
Setting up zipmerge (1.11.3-2) ...
Setting up liberror-perl (0.17030-1) ...
Setting up zip (3.0-15) ...
Setting up libx11-data (2:1.8.12-1) ...
Setting up zlib1g-dev:amd64 (1:1.3.dfsg+really1.3.1-1+b1) ...
Setting up zipcmp (1.11.3-2) ...
Setting up git-man (1:2.47.3-0+deb13u1) ...
Setting up libx11-6:amd64 (2:1.8.12-1) ...
Setting up libngtcp2-16:amd64 (1.11.0-1+deb13u1) ...
Setting up libfido2-1:amd64 (1.15.0-1+b1) ...
Setting up ziptool (1.11.3-2) ...
Setting up libxmuu1:amd64 (2:1.1.3-3+b4) ...
Setting up libngtcp2-crypto-gnutls8:amd64 (1.11.0-1+deb13u1) ...
Setting up libzip-dev:amd64 (1.11.3-2) ...
Setting up openssh-client (1:10.0p1-7+deb13u2) ...
Setting up libcurl3t64-gnutls:amd64 (8.14.1-2+deb13u2) ...
Setting up libxext6:amd64 (2:1.3.4-1+b3) ...
Setting up git (1:2.47.3-0+deb13u1) ...
Setting up xauth (1:1.1.2-1.1) ...
Processing triggers for libc-bin (2.41-12+deb13u2) ...
Configuring for:
PHP Api Version:         20230831
Zend Module Api No:      20230831
Zend Extension Api No:   420230831
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for a sed that does not truncate output... /usr/bin/sed
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether cc accepts -g... yes
checking for cc option to enable C11 features... none needed
checking how to run the C preprocessor... cc -E
checking for egrep -e... (cached) /usr/bin/grep -E
checking for icc... no
checking for suncc... no
checking for system library directory... lib
checking if compiler supports -Wl,-rpath,... yes
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for PHP prefix... /usr/local
checking for PHP includes... -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib
checking for PHP extension directory... /usr/local/lib/php/extensions/no-debug-non-zts-20230831
checking for PHP installed headers prefix... /usr/local/include/php
checking if debug is enabled... no
checking if zts is enabled... no
checking for gawk... no
checking for nawk... nawk
checking if nawk is broken... no
checking for zip archive read/write support... yes, shared
checking for libzip >= 0.11 libzip != 1.3.1 libzip != 1.7.0... yes
checking for zip_file_set_mtime in -lzip... yes
checking for zip_file_set_encryption in -lzip... yes
checking for zip_libzip_version in -lzip... yes
checking for zip_register_progress_callback_with_state in -lzip... yes
checking for zip_register_cancel_callback_with_state in -lzip... yes
checking for zip_compression_method_supported in -lzip... yes
checking for a sed that does not truncate output... /usr/bin/sed
checking for ld used by cc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for /usr/bin/ld option to reload object files... -r
checking for BSD-compatible nm... /usr/bin/nm -B
checking whether ln -s works... yes
checking how to recognize dependent libraries... pass_all
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking the maximum length of command line arguments... 1572864
checking command to parse /usr/bin/nm -B output from cc object... ok
checking for objdir... .libs
checking for ar... ar
checking for ranlib... ranlib
checking for strip... strip
checking if cc supports -fno-rtti -fno-exceptions... no
checking for cc option to produce PIC... -fPIC
checking if cc PIC flag -fPIC works... yes
checking if cc static flag -static works... yes
checking if cc supports -c -o file.o... yes
checking whether the cc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no

creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h
/bin/bash /usr/src/php/ext/zip/libtool --tag=CC --mode=compile cc -I. -I/usr/src/php/ext/zip -I/usr/src/php/ext/zip/include -I/usr/src/php/ext/zip/main -I/usr/src/php/ext/zip -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib  -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE    -DZEND_COMPILE_DL_EXT=1 -c /usr/src/php/ext/zip/php_zip.c -o php_zip.lo  -MMD -MF php_zip.dep -MT php_zip.lo
mkdir .libs
 cc -I. -I/usr/src/php/ext/zip -I/usr/src/php/ext/zip/include -I/usr/src/php/ext/zip/main -I/usr/src/php/ext/zip -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DZEND_COMPILE_DL_EXT=1 -c /usr/src/php/ext/zip/php_zip.c -MMD -MF php_zip.dep -MT php_zip.lo  -fPIC -DPIC -o .libs/php_zip.o
/bin/bash /usr/src/php/ext/zip/libtool --tag=CC --mode=compile cc -I. -I/usr/src/php/ext/zip -I/usr/src/php/ext/zip/include -I/usr/src/php/ext/zip/main -I/usr/src/php/ext/zip -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib  -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE    -DZEND_COMPILE_DL_EXT=1 -c /usr/src/php/ext/zip/zip_stream.c -o zip_stream.lo  -MMD -MF zip_stream.dep -MT zip_stream.lo
 cc -I. -I/usr/src/php/ext/zip -I/usr/src/php/ext/zip/include -I/usr/src/php/ext/zip/main -I/usr/src/php/ext/zip -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DZEND_COMPILE_DL_EXT=1 -c /usr/src/php/ext/zip/zip_stream.c -MMD -MF zip_stream.dep -MT zip_stream.lo  -fPIC -DPIC -o .libs/zip_stream.o
/bin/bash /usr/src/php/ext/zip/libtool --tag=CC --mode=link cc -shared -I/usr/src/php/ext/zip/include -I/usr/src/php/ext/zip/main -I/usr/src/php/ext/zip -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib  -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H  -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE  -Wl,-O1 -pie  -o zip.la -export-dynamic -avoid-version -prefer-pic -module -rpath /usr/src/php/ext/zip/modules  php_zip.lo zip_stream.lo -lzip
cc -shared  .libs/php_zip.o .libs/zip_stream.o  -lzip  -Wl,-O1 -Wl,-soname -Wl,zip.so -o .libs/zip.so
creating zip.la
(cd .libs && rm -f zip.la && ln -s ../zip.la zip.la)
/bin/bash /usr/src/php/ext/zip/libtool --tag=CC --mode=install cp ./zip.la /usr/src/php/ext/zip/modules
cp ./.libs/zip.so /usr/src/php/ext/zip/modules/zip.so
cp ./.libs/zip.lai /usr/src/php/ext/zip/modules/zip.la
PATH="$PATH:/sbin" ldconfig -n /usr/src/php/ext/zip/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/src/php/ext/zip/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

+ strip --strip-all modules/zip.so
Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20230831/
Xdebug: [Log Files] File '/tmp/xdebug.log' could not be opened.
Xdebug: [Log Files] File '/tmp/xdebug.log' could not be opened.
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
find . -name \*.lo -o -name \*.o -o -name \*.dep | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la      modules/* libs/*
rm -f ext/opcache/jit/zend_jit_x86.c
rm -f ext/opcache/jit/zend_jit_arm64.c
rm -f ext/opcache/minilua

2-2. Twigのインストール
var/www/prophp_sample フォルダに Twig をインストールする。

実行結果:
root@3d8258bc2177:/var/www/prophp_sample# composer require twig/twig
Xdebug: [Log Files] File '/tmp/xdebug.log' could not be opened.
The repository at "/var/www/prophp_sample" does not have the correct ownership and git refuses to use it:

fatal: detected dubious ownership in repository at '/var/www/prophp_sample'
To add an exception for this directory, call:

git config --global --add safe.directory /var/www/prophp_sample

./composer.json has been updated
The repository at "/var/www/prophp_sample" does not have the correct ownership and git refuses to use it:

fatal: detected dubious ownership in repository at '/var/www/prophp_sample'
To add an exception for this directory, call:

git config --global --add safe.directory /var/www/prophp_sample

Running composer update twig/twig
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 4 installs, 0 updates, 0 removals
  - Downloading symfony/polyfill-mbstring (v1.37.0)
  - Downloading symfony/polyfill-ctype (v1.37.0)
  - Downloading symfony/deprecation-contracts (v3.7.0)
  - Downloading twig/twig (v3.24.0)
  - Installing symfony/polyfill-mbstring (v1.37.0): Extracting archive
  - Installing symfony/polyfill-ctype (v1.37.0): Extracting archive
  - Installing symfony/deprecation-contracts (v3.7.0): Extracting archive
  - Installing twig/twig (v3.24.0): Extracting archive
Generating autoload files
4 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
Using version ^3.24 for twig/twig

PHP 学習:プロになるためのPHPプログラミング入門 サンプル環境構築

更新:2026.06.06(土) 22:09
公開:2026.05.11(月) 09:46

プロになるためのPHPプログラミング入門 サンプル環境構築

書籍:プロになるためのPHPプログラミング入門
(ISBN:978-4-7741-4972-1)

この書籍のサンプルプログラムを動かすためのコンテナを作成する。
本来であれば新たに専用Dockerコンテナを作成するのが良しと思うが、
今回は「Docker:WSL+Docker+PHP+MySQL+phpMyAdmin環境の作成」で作成したコンテナに環境を作ろうと思う。

DocumentRootは/var/www/html(WSLの./www/html/にマウント)としているが、
compose.yamlに「Apache:エイリアスの設定」の設定を追加し、 サンプルプログラム(prophp_sample)を localhost/prophp_sample で公開するように対応する。

現在の環境
現在の環境は、WSLの "~/docker/php"フォルダ にcompose.yamlなどDocker関連のファイル および
"~/docker/php/www/html"フォルダ にDocumentRoot をマウントしている。

サンプルプログラムの環境
本付属サンプル "prophp_sample.zip" は解凍したのち WSLの "~/docker/php/prophp_sample" フォルダに配置した。
これをコンテナの "/var/www/prophp_sample" フォルダへマウントする。

(2026.06.06 追加)
Dockerfile
mysqliを使いたいので php:8.3-apache のイメージファイルに mysqli を追加する Dockerfileを作成する。
# 現在お使いのイメージをベースにします
FROM php:8.3-apache

# mysqli 拡張機能をインストールするコマンドを追加します
RUN docker-php-ext-install mysqli

compose.yaml
(2026.06.06 修正) php:8.3-apacheイメージを使い代わりに mysqliを組み込んだDockerfileを使うように修正
services:
    php:
      # image: php:8.3-apache
    volumes:
      - ./www/html:/var/www/html
+     - ./prophp_sample:/var/www/prophp_sample
      - ./php.ini-debug:/usr/local/etc/php/php.ini
 :

Apacheのエイリアス設定を行うための prophp_sample.conf ファイルをWSL上に作成する。
prophp_sample.conf
Alias /prophp_sample /var/www/prophp_sample/www

<Directory /var/www/prophp_sample/www>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

prophp_sample.confをコンテナにマウントし、Apacheの設定有効化と起動をcompose.yamlに追加する。
compose.yaml
  services:
    php:
      image: php:8.3-apache
      volumes:
        - ./www/html:/var/www/html
        - ./prophp_sample:/var/www/prophp_sample
        - ./php.ini-debug:/usr/local/etc/php/php.ini
+       - ./prophp_sample.conf:/etc/apache2/conf-available/prophp_sample.conf
      ports:
        - "8080:80"
+     command: >
+       sh -c "a2enconf prophp_sample && apache2-foreground"
 :

あとは "docker copmose up -d" でコンテナを起動、 試しに "~/docker/php/prophp_sample/phpinfo.php" ファイルを作成、"localhost:8080/prophp_sample/phpinfo.php" でアクセスできればOK

参考(全体ソース)

Dockerfile
# 現在お使いのイメージをベースにします
FROM php:8.3-apache

# mysqli 拡張機能をインストールするコマンドを追加します
RUN docker-php-ext-install mysqli

compose.yaml
services:
  php:
    image: php:8.3-apache
    volumes:
      - ./www/html:/var/www/html
      - ./prophp_sample:/var/www/prophp_sample
      - ./php.ini-debug:/usr/local/etc/php/php.ini
      - ./prophp_sample.conf:/etc/apache2/conf-available/prophp_sample.conf
    ports:
      - "8080:80"
    command: >
      sh -c "a2enconf prophp_sample && apache2-foreground"

  db:
    image: mysql:8.0
    volumes:
      - ./mysql:/var/lib/mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
  
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - "8081:80"
    environment:
      PMA_HOST: db

サンプル動作確認

・ p14mbchk.php (P.42 OK)
・ p14mbstr.php (P.43 OK)
・ p15flexyform.php

"PHP 学習"

PHP学習:ログイン認証について

公開:2026.05.10(日) 19:36

PHP学習:ログイン認証について

書籍:プロになるためのPHPプログラミング入門
4.1 ログイン認証の仕組みを作るには (P.130)

ログイン機能の流れ

1. ユーザーがユーザー名とパスワードをサーバーに送信する
2. 入力値をチェックする
3. ユーザー名と一致するユーザー情報をデータベースから1件取得する
4. ユーザーが入力したパスワードとデータベースから取得したパスワードを照合する
5. 認証に成功したときはセッション管理を開始する
6. 認証成功後の画面にリダイレクトする

ログアウト機能の流れ

1. ユーザーのログアウト要求をサーバーに送信する
2. セッションデータを削除する
3. ログイン画面に繊維、クッキーのセッションID削除をWebブラウザに要求する

Git:GitHubレポジトリのPublic/Private変更方法

公開:2026.05.10(日) 17:19

GitHubレポジトリのPublic/Private変更方法

レポジトリの "Settings" - "General" ページの末尾に "Danger Zone" がある。
そこの "Change repository visibility" という項目の [Change visibility] ボタンをクリックする。
これでPrivateに変更できる。


"Git 学習"

Git:GitHubへのアップロード方法

公開:2026.05.10(日) 14:48

GitHubへのアップロード方法

JavaScriptの学習(JavaScript #9:電卓に1文字消すボタンを追加する)のソースコードをローカルのGitで管理していたが、これをGitHubへアップロードしてみようと思う。

1. GitHubアカウントの登録
登録済みなのでスキップ

2. 新しいレポジトリの作成
◆ GitHubの自分のDashboardページ右上の [+]ボタンより "New repository" をクリック

◆ Repository nameの入力と 公開設定(Public/Private)を選択し [Create repository] ボタンをクリック

◆ レポジトリを作成するとアップロード方法が表示される
新規の場合は "…or create a new repository on the command line" に書かれたコマンドw実行
既にGitで管理している場合は "…or push an existing repository from the command line" に書かれたコマンドを実行

◆ git push時にエラーが出る場合
"git push -u origin" を実行したところ以下のメッセージが表示された
xxx@xxx:~/docker/node.js/calc-vite$ git push -u origin
fatal: The current branch main has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin main

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

これはローカルの main と GitHubの main が紐付いていない、というメッセージらしい。
メッセージに表示されたコマンド "git push --set-upstream origin main" を実行することで対応
xxx@xxx:~/docker/node.js/calc-vite$ git push --set-upstream origin main
Username for 'https://github.com': xxx
Password for 'https://xxx@github.com':
remote: Invalid username or token. Password authentication is not supported for Git operations.
fatal: Authentication failed for 'https://github.com/xxx/CALC-VITE.git/'

またまたエラー。
GitHubではセキュリティ向上のため、2021年から通常のパスワードでの認証が廃止された?
PAT(Personal Access Token)という「Git操作専用の合言葉」を発行して入力することにする。

1. Githubでトークン(PAT)を発行
1. https://github.com/settings/tokens を開く

2. [Generate new toke] → [Generate new token (classic)

3. Noteの入力、"repo"へチェックを付け [Generate token] をクリック

4. "ghp_"で始まるトークンをメモしておく

2. "git push -u origin main" コマンドを実行
ユーザー名を入力し、パスワードには先程メモしたトークンを入力
xxx@xxx:~/docker/node.js/calc-vite$ git push -u origin main
Username for 'https://github.com': xxx
Password for 'https://xxx@github.com':
Enumerating objects: 36, done.
Counting objects: 100% (36/36), done.
Delta compression using up to 24 threads
Compressing objects: 100% (36/36), done.
Writing objects: 100% (36/36), 29.86 KiB | 5.97 MiB/s, done.
Total 36 (delta 13), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (13/13), done.
To https://github.com/xxx/CALC-VITE.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

これでGitHubにアップされた。


"Git 学習"

JavaScript #9:電卓に1文字消すボタンを追加する

公開:2026.05.10(日) 12:42

電卓に1文字消すボタンを追加する

打ち間違えた際に1文字削除するための1文字削除(バックスペース)キーを追加してみる。
この機能を実装するには、JavaScriptの文字列操作(Slice)を使う。
VB.NETでは String.Substring や、1文字削る String.Remove に相当。

1. index.html修正
"C"(クリア)ボタンの隣あたりに、バックスペースボタンを追加する。
  <button>C</button>
+ <button id="backspace">⌫</button>
  <button>=</button>

2. calculatorLogic.js修正 1文字削除する deleteLastChar メソッドを追加する。
export function deleteLastChar(currentValue) {
    // 1文字削った結果を返す
    return currentValue.slice(0, -1);
}

3. main.js修正
deleteLastCharメソッドをインポート、button.id=backspace クリック時にdeleteLastCharメソッドを呼び出すように修正する。

  import './style.css'
- import { calculate, clearDisplay } from './calculatorLogic.js'
+ import { calculate, clearDisplay, deleteLastChar } from './calculatorLogic.js'
 :
  buttons.forEach(button => {
      button.addEventListener('click', () => {
          const value = button.textContent;
  
+         if (button.id === 'backspace') {
+            display.value = deleteLastChar(display.value);
+             return;
+         }
 ;

参考(全体ソース)

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Vite 電卓</title>
  </head>
  <body>
    <div id="app">
      <!-- ここに電卓のHTMLを貼り付けます -->
      <div id="calculator">
          <input type="text" id="display" readonly>
          <div class="buttons">
              <button>7</button><button>8</button><button>9</button><button>/</button>
              <button>4</button><button>5</button><button>6</button><button>*</button>
              <button>1</button><button>2</button><button>3</button><button>-</button>
              <button>0</button>
              <button>C</button>
              <button id="backspace">⌫</button>
              <button>=</button>
              <button>+</button>
          </div>
      </div>
      <div id="history-container">
        <h3>計算機能</h3>
        <ul id="history-list"></ul>
        <button id="clear-history">履歴をクリア</button>
      </div>
    </div>
    <script type="module" src="./src/main.js"></script>
  </body>
</html>

calculatorLogic.js
// calculatorLogic.js の先頭に必要です
import { evaluate } from 'mathjs';

export function calculate(expression) {
    try {
        return evaluate(expression); // window.math ではなく直接 evaluate を使う
    } catch (error) {
        console.error("計算エラー:", error); 
        return 'Error';
    }
}

export function clearDisplay() {
    return '';
}

export function deleteLastChar(currentValue) {
    // 1文字削った結果を返す
    return currentValue.slice(0, -1);
}

main.js
import './style.css'
import { calculate, clearDisplay, deleteLastChar } from './calculatorLogic.js'

const display = document.getElementById('display');
const buttons = document.querySelectorAll('#calculator .buttons button');
// 履歴を表示するulノード
const historyList = document.getElementById('history-list');
// 履歴をクリアするボタン
const clearHistoryBtn = document.getElementById('clear-history');

// 履歴を格納するための historyData配列 を追加
let historyData = [];

buttons.forEach(button => {
    button.addEventListener('click', () => {
        const value = button.textContent;
 
        if (button.id === 'backspace') {
            display.value = deleteLastChar(display.value);
            return;
        }

        if (value === 'C') {
            display.value = clearDisplay();
        } else if (value === '=') {
            // "="の処理で historyData配列 へ値の追加と liノードの追加
            const expression = display.value;
            const result = calculate(display.value);

            if (result !== 'Error') {
                historyData.unshift(`${expression} = ${result}`);
                renderHistory();
                saveHistory();
            }
            display.value = result;
        } else {
            display.value += value;
        }
    });
});

// 履歴クリア処理
function renderHistory() {
    historyList.innerHTML = '';

    historyData.forEach(item => {
        const li = document.createElement('li');
        li.textContent = item;
        historyList.appendChild(li);
    });
}

//  履歴をクリアボタンにイベント登録
clearHistoryBtn.addEventListener('click', () => {
    historyData = [];
    renderHistory();
});

// ローカルストレージへの保存
function saveHistory() {
    // 配列をJSON文字列に変換して保存
    localStorage.setItem('calculator-history', JSON.stringify(historyData));
}

// ローカルストレージからの復元
function loadHistory() {
    const savedData = localStorage.getItem('calculator-history');
    if (savedData) {
        // JSON文字列を配列に戻す
        historyData = JSON.parse(savedData);
        renderHistory();
    }
}

// 起動時に実行
loadHistory();


"JavaScript 学習"

JavaScript #8:電卓の履歴をローカルストレージに保存する

公開:」2026.05.09(土) 18:38

電卓の履歴をローカルストレージに保存する

1. LocalStorage(ローカルストレージ)
ブラウザにデータを保存するための仕組み
VB.NETでいうところの「設定ファイル(App.config / Settings.settings)」や「簡易的なXML保存」に近い感覚
サーバーやデータベースを用意しなくても、ユーザーのブラウザ内にデータが残り続ける

2. LocalStorageの特徴
・永続性:ブラウザを閉じても、PCを再起動してもデータは消えない
・容量:約5MBまで
・形式:文字列(String)のみ

3. main.js修正
◆ "="ボタンクリックの差異、履歴(historyData配列)を文字列へ変換しLocalStorageに"calculate-history"の名前で保存
 :
} else if (value === '=') {
 :
    if (result !== 'Error') {
        historyData.unshift(`${expression} = ${result}`);
        renderHistory();
        saveHistory();
 :
// ローカルストレージへの保存
function saveHistory() {
    // 配列をJSON文字列に変換して保存
    localStorage.setItem('calculator-history', JSON.stringify(historyData));
}

◆ アプリ起動時にLocalStorageより"calculate-history"のデータを取り出し配列に変換、historyData配列に保存
また、renderHistoryメソッドを呼び出し画面に履歴を描画する
// ローカルストレージからの復元
function loadHistory() {
    const savedData = localStorage.getItem('calculator-history');
    if (savedData) {
        // JSON文字列を配列に戻す
        historyData = JSON.parse(savedData);
        renderHistory();
    }
}

// 起動時に実行
loadHistory();

これで ブラウザでF5キーでリロード しても履歴が消えなくなる

参考(全体ソース)

main.js
import './style.css'
import { calculate, clearDisplay } from './calculatorLogic.js'
 
const display = document.getElementById('display');
const buttons = document.querySelectorAll('#calculator .buttons button');
// 履歴を表示するulノード
const historyList = document.getElementById('history-list');
// 履歴をクリアするボタン
const clearHistoryBtn = document.getElementById('clear-history');

// 履歴を格納するための historyData配列 を追加
let historyData = [];

buttons.forEach(button => {
    button.addEventListener('click', () => {
        const value = button.textContent;
 
        if (value === 'C') {
            display.value = clearDisplay();
        } else if (value === '=') {
            // "="の処理で historyData配列 へ値の追加と liノードの追加
            const expression = display.value;
            const result = calculate(display.value);

            if (result !== 'Error') {
                historyData.unshift(`${expression} = ${result}`);
                renderHistory();
                saveHistory();
            }
            display.value = result;
        } else {
            display.value += value;
        }
    });
});

// 履歴クリア処理
function renderHistory() {
    historyList.innerHTML = '';

    historyData.forEach(item => {
        const li = document.createElement('li');
        li.textContent = item;
        historyList.appendChild(li);
    });
}

//  履歴をクリアボタンにイベント登録
clearHistoryBtn.addEventListener('click', () => {
    historyData = [];
    renderHistory();
});

// ローカルストレージへの保存
function saveHistory() {
    // 配列をJSON文字列に変換して保存
    localStorage.setItem('calculator-history', JSON.stringify(historyData));
}

// ローカルストレージからの復元
function loadHistory() {
    const savedData = localStorage.getItem('calculator-history');
    if (savedData) {
        // JSON文字列を配列に戻す
        historyData = JSON.parse(savedData);
        renderHistory();
    }
}

// 起動時に実行
loadHistory();

"JavaScript 学習"

JavaScript:学習記事一覧

更新:2026.05.10(日) 13:34
公開:2026.05.09(土) 01:39

JavaScript 学習記事一覧



"JavaScript 学習"

JavaScript #6:自作の処理を別ファイルにする

公開:2026.05.07(木) 20:33

JavaScriptで自作の処理を別ファイルにしてimportしてみる

前回記事:「JavaScript #5:電卓アプリをVite対応にする」の続き。
自作の処理を別ファイルに切り出して import する、という工程にステップアップしてみる。
今回の目標は、電卓の計算ロジックだけを calculatorLogic.js という別ファイルに分離すること。

1. calculatorLogic.js作成
calc-vite\src\calculatorLogic.js ファイルを新規作成
// calculatorLogic.js の先頭に必要です
import { evaluate } from 'mathjs';

export function calculate(expression) {
    try {
        return evaluate(expression); // window.math ではなく直接 evaluate を使う
    } catch (error) {
        console.error("計算エラー:", error); 
        return 'Error';
    }
}

export function clearDisplay() {
    return '';
}
    

2. main.js修正
calc-vite\src\main.js ファイルを修正、
calculatorLogic.jsを読み込むように変更する。
import './style.css'
// 自作ファイルから特定の関数をインポート({ } を使う!)
import { calculate, clearDisplay } from './calculatorLogic.js'

const display = document.getElementById('display');
const buttons = document.querySelectorAll('button');

buttons.forEach(button => {
    button.addEventListener('click', () => {
        const value = button.textContent;

        if (value === 'C') {
            display.value = clearDisplay();
        } else if (value === '=') {
            display.value = calculate(display.value);
        } else {
            display.value += value;
        }
    });
});
    

"JavaScript 学習"

JavaScript #5:電卓アプリをVite対応にする

公開:2026.05.07(木) 09:37

電卓アプリをVite対応にする

以下記事で作成した簡易電卓をVite対応に変更してみる。 ※ JavaScript #2:簡単な電卓を作る
JavaScript #3:ライブラリを使ってみる
JavaScript #4:ビルドツールについて

1. index.htmlの編集
calc-vite\index.htmlを編集する。
主なポイントは、
・styleはstyle.cssに記載するのですべて削除
 style.cssの読み込みもmain.jsで行うので記載しない
・jsはmain.jsに記載するのですべて削除
 main.jsを読み込むようにする。
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Vite 電卓</title>
  </head>
  <body>
    <div id="app">
      <!-- ここに電卓のHTMLを貼り付けます -->
      <div id="calculator">
          <input type="text" id="display" readonly>
          <div class="buttons">
              <button>7</button><button>8</button><button>9</button><button>/</button>
              <button>4</button><button>5</button><button>6</button><button>*</button>
              <button>1</button><button>2</button><button>3</button><button>-</button>
              <button>0</button>
              <button>C</button>
              <button>=</button>
              <button>+</button>
          </div>
      </div>
    </div>
    <script type="module" src="./src/main.js"></script>
  </body>
</html>      
    

2. main.jsの編集
calc-vite\src\main.jsを編集する。
主なポイントは、
・style.cssもimportで読み込む
・math.jsをimportして使う
import './style.css'
import { evaluate } from 'mathjs'

const display = document.getElementById('display');
const buttons = document.querySelectorAll('button');

buttons.forEach(button => {
    button.addEventListener('click', () => {
        const value = button.textContent;

        if (value === 'C') {
            display.value = '';
        } else if (value === '=') {
            try {
                // インポートした evaluate 関数を使う
                display.value = evaluate(display.value);
            } catch (e) {
                display.value = 'Error';
            }
        } else {
            display.value += value;
        }
    });
});    
    

3. style.cssの編集
calc-vite\src\style.cssを編集する。
body {
    display: flex;
    justify-content: center; /* 横方向の中央 */
    align-items: center;    /* 縦方向の中央 */
    height: 100vh;         /* 画面いっぱいの高さ */
    background-color: #f0f0f0;
    margin: 0;
}

#calculator {
    background-color: #333;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 10px 25px rgba(0,0,0,0.3);
}

/* 表示画面のスタイル */
#display {
    width: 100%;
    height: 50px;
    font-size: 24px;
    text-align: right;
    margin-bottom: 10px;
    padding: 10px;
    box-sizing: border-box; /* パディングを含めたサイズ計算 */
    border: none;
    border-radius: 5px;
}
.buttons {
    display: grid;
    /* 4つの列を同じ幅(1fr)で作る */
    grid-template-columns: repeat(4, 1fr); 
    /* ボタン同士の隙間 */
    gap: 10px;
}

button {
    padding: 20px;
    font-size: 18px;
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #eee;
    transition: background-color 0.2s; /* ホバー時のアニメーション */
}

/* マウスが乗った時 */
button:hover {
    background-color: #ddd;
}

/* 計算ボタンなどの色を変える(お好みで) */
button:nth-child(4n) {
    background-color: #ff9500;
    color: white;
}
.wide {
    grid-column: span 2;
}
    

これで電卓が動作する。

"JavaScript 学習"

JavaScript #4:ビルドツールについて

公開:2026.05.06(水) 23:45

JavaScriptのビルドツール

Web開発における「ビルド」とは、「開発者が書きやすいコード」を「ブラウザが読みやすいコード」に変換・最適化する工程のこと、らしい。

なぜビルドが必要なのか?
現代のWeb開発では、ブラウザが直接理解できない技術をたくさん使用する。
・ TypeScript: ブラウザは実行できないので、JavaScriptに変換する必要がある。
・ モジュール管理: 多くのライブラリ(math.jsなど)を組み合わせて使う際、バラバラのファイルを1つにまとめた方が
読み込みが速い。
・ 最適化: コード内の不要な改行やスペースを削り、ファイルサイズを極限まで小さくする(Minify)。

トレンドのツール:Vite(ヴィート)らしい。

前回作成した簡易電卓(JavaScript #3:ライブラリを使ってみる) をViteを使ったプロジェクトへアップグレードしてみる。

1. Viteプロジェクトの作成
既存の ~/docker/node.js フォルダで作業しても良いが、新しく calc-vite というプロジェクトを作ることにする。
WSL(Ubuntu)で以下コマンドを実行
質問はすべてEnterで進める。
docker compose exec app npm create vite@latest calc-vite -- --template vanilla

※ --template vanilla … ReactやVueといったフレームワークを使わない、純粋なJavaScriptプロジェクトを作成

実行結果:
xxx@xxx:~/docker/node.js$ docker compose exec app npm create vite@latest calc-vite -- --template vanilla
Need to install the following packages:
create-vite@9.0.6
Ok to proceed? (y)


> app@1.0.0 npx
> create-vite calc-vite --template vanilla

│
◇  Install with npm and start now?
│  Yes
│
◇  Scaffolding project in /app/calc-vite...
│
◇  Installing dependencies with npm...

added 15 packages, and audited 16 packages in 8s

8 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
│
◇  Starting dev server...

> calc-vite@0.0.0 dev
> vite


  VITE v8.0.10  ready in 269 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
    
Viteの画面で止まるのでCTRL+Cで終了。
プロジェクトディレクトリ配下に calc-vite フォルダが作成される。

2. フォルダ構成の変更
プロジェクトフォルダの compose.yaml の volumes 設定を変更し、新しいプロジェクトフォルダをマウントするようにする。
services:
  app:
    image: node:20-slim
    user: "node"
    volumes:
      - ./calc-vite:/app  # 作成したプロジェクトフォルダをマウント
    working_dir: /app
    ports:
      - "5173:5173"       # Viteのデフォルトポートに変更
    command: npm run dev  # Viteの開発用サーバーを起動
    tty: true      
    

Viteはコンテナ外からの接続を許可していないらしく、WindowsからViteにアクセスできない。
"npm run dev"した場合はWindowsからでもアクセスできるように calc-vite\package.json の以下設定を変更する。
    "dev": "vite --host",
    

3. 初期セットアップと起動
設定を書き換えたら、以下の手順でコンテナを再起動し、必要なライブラリをインストールする。
# 一旦止めて再起動
docker compose down
docker compose up -d

# ライブラリのインストール
docker compose exec app npm install

# 再度 mathjs をインストール
docker compose exec app npm install mathjs

実行結果:
xxx@xxx:~/docker/node.js$ docker compose down
[+] down 2/2
 ✔ Container nodejs-app-1 Removed                                                                       1.0s
 ✔ Network nodejs_default Removed                                                                       0.2s
xxx@xxx:~/docker/node.js$ docker compose up -d
[+] up 2/2
 ✔ Network nodejs_default Created                                                                       0.0s
 ✔ Container nodejs-app-1 Started                                                                       0.2s
xxx@xxx:~/docker/node.js$ docker compose exec app npm install

added 2 packages, and audited 18 packages in 766ms

9 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
xxx@xxx:~/docker/node.js$ docker compose exec app npm install mathjs

added 10 packages, and audited 28 packages in 1s

11 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
    

4. 動作確認
Windowsでブラウザを起動し http://localhost:5173 へアクセスしViteの初期画面が表示されればOK

5. Viteプロジェクトのファイル構成
Viteプロジェクトフォルダの主要はフォルダ・ファイル
・ index.html:アプリの入り口
・ main.js:プログラムのメイン処理。VB.NETの Main() メソッドに近い役割
・ style.css: デザイン(CSS)を書く場所
・ public/ フォルダ: 画像など、そのまま公開したいファイルを置く場所

"JavaScript 学習"

JavaScript #2:簡単な電卓を作る

公開:2026.05.05(火) 09:13

JavaScriptで簡単な電卓を作る

1. 環境

DockerでNode.js環境を作っておく

2. HTMLの作成

body内に結果を表示するtext(id=display)と、計算ボタンを16個作成する。
<div id="calculator">
    <input type="text" id="display" readonly>
    <div class="buttons">
        <button>7</button><button>8</button><button>9</button><button>/</button>
        <button>4</button><button>5</button><button>6</button><button>*</button>
        <button>1</button><button>2</button><button>3</button><button>-</button>
        <button>0</button><button>C</button><button>=</button><button>+</button>
    </div>
</div>
    

3. デザイン

index.htmlの <head> タグ内に <style> タグを追加しCSSコードを記述する。

1. body
body {
    display: flex;
    justify-content: center; /* 横方向の中央 */
    align-items: center;    /* 縦方向の中央 */
    height: 100vh;         /* 画面いっぱいの高さ */
    background-color: #f0f0f0;
    margin: 0;
}
      
2. #calculator (電卓全体)
#calculator {
    background-color: #333;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 10px 25px rgba(0,0,0,0.3);
}
      
3. #display (結果表示欄)
#display {
    width: 100%;
    height: 50px;
    font-size: 24px;
    text-align: right;
    margin-bottom: 10px;
    padding: 10px;
    box-sizing: border-box; /* パディングを含めたサイズ計算 */
    border: none;
    border-radius: 5px;
}
      
4. .buttons (ボタン全体)
.buttons {
    display: grid;
    /* 4つの列を同じ幅(1fr)で作る */
    grid-template-columns: repeat(4, 1fr); 
    /* ボタン同士の隙間 */
    gap: 10px;
}
      
5. button (ボタン)
button {
    padding: 20px;
    font-size: 18px;
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #eee;
    transition: background-color 0.2s; /* ホバー時のアニメーション */
}
/* マウスが乗った時 */
button:hover {
    background-color: #ddd;
}
/* 計算ボタンなどの色 (左から4つめのボタンの色) */
button:nth-child(4n) {
    background-color: #ff9500;
    color: white;
}
      

4. JavaScriptコード

index.htmlの </body> の直前に <script> タグを追加しJavaScriptコードを記述する。
<script>
    const display = document.getElementById('display');
    const buttons = document.querySelectorAll('button');

    buttons.forEach(button => {
        button.addEventListener('click', () => {
            const value = button.textContent;

            if (value === 'C') {
                display.value = ''; // クリア
            } else if (value === '=') {
                try {
                    display.value = eval(display.value);
                } catch {
                    display.value = 'Error';
                }
            } else {
                display.value += value; // 数字や記号を連結
            }
        });
    });
</script>
    

5. 完成


"JavaScript 学習"

JavaScript #1:node環境の構築

公開:2026.05.03(日) 19:36

JavaScriptの開発環境をDockerで構築する

JavaScriptの学習をするため、Docker上にnode.js環境の構築をすることにした。

Docker環境

1. Windows+WSL+Ubuntu上にDockerを構築


2. 作業フォルダ作成

WSL上に "~/docker/node.js" フォルダを作成した。
mkdir -p ~/docker/node.js
cd ~/docker/node.js

3. compose.yamlファイル作成

VSCodeを起動
xxx@xxx:~/docker/node.js$ code .

compose.yaml
services:
  app:
    image: node:20-slim
    volumes:
      - .:/app
    working_dir: /app
    ports:
      - "3000:3000"
    tty: true

4. コンテナ起動

WSLターミナル、またはVSCodeのターミナル(CTRL+@)で以下コマンドを実行
docker compose up -d

実行結果:
xxx@xxx:~/docker/node.js$ docker compose up -d
[+] up 10/10
 ✔ Image node:20-slim     Pulled                                                                                   11.1s
 ✔ Network nodejs_default Created                                                                                   0.1s
 ✔ Container nodejs-app-1 Started

5. 簡易サーバー起動

コンテナ上で簡易サーバーを起動
docker compose exec app npx serve .

実行結果:
xxx@xxx:~/docker/node.js$ docker compose exec app npx serve .
Need to install the following packages:
serve@14.2.6
Ok to proceed? (y) y

 ERROR  Cannot copy server address to clipboard: Couldn't find the `xsel` binary and fallback didn't work. On Debian/Ubuntu you can install xsel with: sudo apt install xsel.

   ┌────────────────────────────────────────┐
   │                                        │
   │   Serving!                             │
   │                                        │
   │   - Local:    http://localhost:3000    │
   │   - Network:  http://172.19.0.2:3000   │
   │                                        │
   └────────────────────────────────────────┘

 HTTP  5/3/2026 11:52:10 AM 172.19.0.1 GET /
 HTTP  5/3/2026 11:52:10 AM 172.19.0.1 Returned 200 in 22 ms
 HTTP  5/3/2026 11:52:10 AM 172.19.0.1 GET /favicon.ico
 HTTP  5/3/2026 11:52:10 AM 172.19.0.1 Returned 404 in 3 ms
 HTTP  5/3/2026 11:52:14 AM 172.19.0.1 GET /
 HTTP  5/3/2026 11:52:14 AM 172.19.0.1 Returned 200 in 1 ms
ERRORと表示されているがxselが入っていないのが原因で特に問題ないらしい

6. 動作テスト

WSLの作業フォルダ上にindex.htmlを作成
VSCodeでは "!" + Enter(または "html:5" + Enter)でhtmlのテンプレートを作成
bodyに適当に文字列を入力しておく。

Windowsのブラウザで「http://localhost:3000」にアクセス、index.htmlの中身が表示されればOK

簡易サーバーは CTRL+D で終了させておく、

7. package.jsonの作成

"npm start" コマンドで簡易サーバーを起動できるようにpackage.jsonを作成する。
WSLにて以下コマンドを実行する。
docker compose exec app npm init -y
docker compose exec app npm install serve

実行結果:
xxx@xxx:~/docker/node.js$ docker compose exec app npm init -y
Wrote to /app/package.json:

{
  "name": "app",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}



xxx@xxx:~/docker/node.js$ docker compose exec app npm install serve

added 85 packages, and audited 86 packages in 2s

26 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

package.jsonはWSL(Ubuntu)の作業用フォルダに作成されており、これを編集したいが書き込み権限が無く編集できない。
WSL(Ubuntu)の作業フォルダ上で以下コマンドを実行し権限を付与する。
sudo chown -R \$USER:$USER .

次にWSLで "code package.json" (またはWindowsのVSCodeからリモートエクスプローラー、もしくは Ubuntu上でvimで) scriptsの部分に "start: serve ." を付加する。
{
  "name": "app",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "serve ."
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "serve": "^14.2.6"
  }
}
これで以下コマンドで簡易サーバーが起動できるようになる。
docker compose exec app npm start

8. コンテナを一般ユーザーで動かす

コンテナ内の動作はコンテナ内のrootユーザーによって動作するため、先ほどのpackage.jsonのようにホストから編集できないファイルが作成される場合がある。
"node:20-slim"イメージには nodeという名前の一般ユーザーが含まれており、このユーザーでコンテナを動かすことでこのトラブルを防ぐことができる。
"node"ユーザーでコンテナを動かすには compose.yaml に "user" 設定を追加する。
services:
  app:
    image: node:20-slim
    user: "node"  # ← これを追加(rootではなく標準ユーザーnodeで動かす)
    volumes:
      - .:/app
    working_dir: /app
    ports:
      - "3000:3000"
    tty: true
設定を反映するには、CTRL+C および compose down でコンテナをいったん停止し compose up で再起動する。
docker compose down
docker compose up -d

9. コンテナ起動時に簡易サーバーも起動させる

現在はコンテナ起動したとに docker compose exec app npm start を実行する必要がる。
コンテナ起動時に npm start を実行させるには compose.yaml に "command" の設定を追加する。
services:
  app:
    image: node:20-slim
    user: "node"
    volumes:
      - .:/app
    working_dir: /app
    ports:
      - "3000:3000"
    # コンテナ起動時に自動で実行されるコマンド
    command: npm start
    tty: true
"docker compose down" → "docker compose up -d" でコンテナを再起動、
Windowsからブラウザで "localhost:3000" にアクセスできれば無事に起動できている。

"JavaScript 学習"

PHP 学習:セッション管理を学ぶ


1. session_name(セッション名) でセッション名を設定
セッションIDを保持するクッキーの名前として使用。
設定しない場合はphp.ini session.name の値となる。

2. session_start関数
セッション管理機能を使うには、はじめに session_start関数を呼び出す
session_startを呼び出した後は $_SESSION変数にアクセスしてセッションデータの読み書きができるようになる。

3. session_regenerate_id関数
セッションIDを生成し直す。
ログイン成功時にセッションIDを変更すること。(セッションハイジャック対策)

4. クッキー削除
setcookie関数でクッキーの有効期限に過去日を設定することで削除する。

5. セッションデータ削除
$_SESSION.= array() でセッション変数のデータを削除
session_destroy関数でサーバーのセッションデータを削除

PHP 学習:HTML_Template_Flexyのインストール

公開:2026.04.18 16:30

HTML_Template_Flexy

書籍「プロになるためのPHPプログラミング入門」で学習しているが、HTML_Template_Flexyというのを使用している。
ということでインストールしてみる。

ちなみに、
https://pear.php.net/package/html_template_flexy/
残念ながら保守されておらず、現在は新規プロジェクトでの採用は非推薦とのこと。

環境

◆ Windows 11 25H2 (26200.8037) + WSL + Docker
◆ WSL:
PS C:\Users\xxx> wsl --version
WSL バージョン: 2.3.24.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.65
MSRDC バージョン: 1.2.5620
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.26200.8037
◆ Ubuntu:
xxx@xxx:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble

PHP環境

過去記事:Docker 学習 #4:Docker Composeを学ぶ で作成したPHPコンテナを使用する。
以下コマンドでコンテナを起動。
docker compose up -d

コンテナのbashに接続する。
docker exec -it (CONTAINER ID) /bin/bash
※ (CONTAINER ID)は "docker ps" コマンドで確認。

PEAR環境

HTML_Template_Flexyをインストールするには PEAR というのが必要。
過去記事:PHP 学習:PEARのインストール の手順で環境を作る。

HTML_Tempalte_Flexyのインストール

以下コマンドでインストールする。
pear install HTML_Template_Flexy

実行結果:(大文字小文字は区別しないみたい)
root@05fa4e42bbcd:/var/www/html# pear install html_template_flexy
Did not download optional dependencies: pear/HTML_Javascript, pear/File_Gettext, pear/Translation2, use --alldeps to download automatically
pear/HTML_Template_Flexy can optionally use package "pear/HTML_Javascript" (version >= 1.1.0)
pear/HTML_Template_Flexy can optionally use package "pear/File_Gettext" (version >= 0.2.0)
pear/HTML_Template_Flexy can optionally use package "pear/Translation2" (version >= 0.0.1)
downloading HTML_Template_Flexy-1.3.13.tgz ...
Starting to download HTML_Template_Flexy-1.3.13.tgz (213,779 bytes)
.............................................done: 213,779 bytes
install ok: channel://pear.php.net/HTML_Template_Flexy-1.3.13
  
以上で完了。


PHP 学習

PHP 学習:PEARのインストール

公開:2026.04.18 11:37

PEAR

PEAR と書いて "ペア"(梨) と呼ぶ。 PEAR = PHP Extension and Application Repository
PHPのライブラリやパッケージを管理するシステムのこと。

いまさらながらPEARを使おうと思っていたが、もう昔のものらしい。
今の主流はComposerとのこと。

図書館で「プロになるためのPHPプログラミング入門」という本を借りたが、出版は2012年2月。
HTML_Template_Flexyというのを使っていて(これも現在は非推薦)、そしてこれを使うにはPEARが必要、ということで先に進むためPEARとHTML_Template_Flexyを入れることにした。

こういう技術本はなるべく最新のものを読まないと苦労する。

環境

◆ Windows 11 25H2 (26200.8037) + WSL + Docker
◆ WSL:
PS C:\Users\xxx> wsl --version
WSL バージョン: 2.3.24.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.65
MSRDC バージョン: 1.2.5620
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.26200.8037
◆ Ubuntu:
xxx@xxx:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble

PHP環境

過去記事:Docker 学習 #4:Docker Composeを学ぶ で作成したPHPコンテナを使用する。
以下コマンドでコンテナを起動。
docker compose up -d

コンテナのbashに接続する。
docker exec -it (CONTAINER ID) /bin/bash
※ (CONTAINER ID)は "docker ps" コマンドで確認。

PEAR環境を作る

Geminiに聞いてみた。

[方法1] パッケージマネージャを使ってインストールする。
apt update
apt install php-pear

実行結果: インストールできなかった
root@xxx:~/docker/php# docker exec -it 05fa4e42bbcd /bin/bash
root@05fa4e42bbcd:/var/www/html# apt update
Hit:1 http://deb.debian.org/debian trixie InRelease
Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9671 kB]
Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [5412 B]
Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [124 kB]
Fetched 9891 kB in 3s (3833 kB/s)
3 packages can be upgraded. Run 'apt list --upgradable' to see them.
root@05fa4e42bbcd:/var/www/html# apt install php-pear
Package php-pear is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

Error: Package 'php-pear' has no installation candidate
  
[方法2] go-pear.pharを使って直接インストールする。
wget http://pear.php.net/go-pear.phar

実行結果:
root@05fa4e42bbcd:/var/www/html# wget http://pear.php.net/go-pear.phar
bash: wget: command not found
  
wgetが無いらしいのでインストール:
root@05fa4e42bbcd:/var/www/html# apt install wget
Installing:
  wget

Summary:
  Upgrading: 0, Installing: 1, Removing: 0, Not Upgrading: 3
  Download size: 984 kB
  Space needed: 3875 kB / 1017 GB available

Get:1 http://deb.debian.org/debian trixie/main amd64 wget amd64 1.25.0-2 [984 kB]
Fetched 984 kB in 0s (3695 kB/s)
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 79,  line 1.)
debconf: falling back to frontend: Readline
Selecting previously unselected package wget.
(Reading database ... 15584 files and directories currently installed.)
Preparing to unpack .../wget_1.25.0-2_amd64.deb ...
Unpacking wget (1.25.0-2) ...
Setting up wget (1.25.0-2) ...
  
もう一度 go-pear.phar のダウンロードをやってみる。
今度はOK!
root@05fa4e42bbcd:/var/www/html# wget http://pear.php.net/go-pear.phar
--2026-04-18 07:17:30--  http://pear.php.net/go-pear.phar
Resolving pear.php.net (pear.php.net)... 109.203.101.62
Connecting to pear.php.net (pear.php.net)|109.203.101.62|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://pear.php.net/go-pear.phar [following]
--2026-04-18 07:17:31--  https://pear.php.net/go-pear.phar
Connecting to pear.php.net (pear.php.net)|109.203.101.62|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3637615 (3.5M)
Saving to: 'go-pear.phar'

go-pear.phar                  100%[=================================================>]   3.47M   318KB/s    in 14s

2026-04-18 07:17:47 (246 KB/s) - 'go-pear.phar' saved [3637615/3637615]
  
続いて インストール実行
php go-pear.phar

実行結果:なにやら色々聞いてきた。[Enter]押せばいいとのこと。
root@05fa4e42bbcd:/var/www/html# php go-pear.phar
PHP Warning:  Private methods cannot be final as they are never overridden by other classes in /var/www/html/go-pear.phar on line 339

Warning: Private methods cannot be final as they are never overridden by other classes in /var/www/html/go-pear.phar on line 339

Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.

 1. Installation base ($prefix)                   : /usr/local
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /usr/local/bin
 5. PHP code directory ($php_dir)                 : /usr/local/lib/php
 6. Documentation directory                       : /usr/local/docs
 7. Data directory                                : /usr/local/data
 8. User-modifiable configuration files directory : /usr/local/cfg
 9. Public Web Files directory                    : /usr/local/www
10. System manual pages directory                 : /usr/local/man
11. Tests directory                               : /usr/local/tests
12. Name of configuration file                    : /usr/local/etc/pear.conf

1-12, 'all' or Enter to continue:    
  
インストール完了:
Beginning install...
Configuration written to /usr/local/etc/pear.conf...
Initialized registry...
Preparing to install...
installing phar:///var/www/html/go-pear.phar/PEAR/go-pear-tarballs/Archive_Tar-1.6.0.tar...
installing phar:///var/www/html/go-pear.phar/PEAR/go-pear-tarballs/Console_Getopt-1.4.3.tar...
installing phar:///var/www/html/go-pear.phar/PEAR/go-pear-tarballs/PEAR-1.10.18.tar...
installing phar:///var/www/html/go-pear.phar/PEAR/go-pear-tarballs/Structures_Graph-1.2.0.tar...
installing phar:///var/www/html/go-pear.phar/PEAR/go-pear-tarballs/XML_Util-1.4.5.tar...
warning: pear/PEAR dependency package "pear/Archive_Tar" downloaded version 1.6.0 is not the recommended version 1.4.4
warning: pear/PEAR dependency package "pear/Structures_Graph" downloaded version 1.2.0 is not the recommended version 1.1.1
install ok: channel://pear.php.net/Archive_Tar-1.6.0
install ok: channel://pear.php.net/Console_Getopt-1.4.3
install ok: channel://pear.php.net/Structures_Graph-1.2.0
install ok: channel://pear.php.net/XML_Util-1.4.5
install ok: channel://pear.php.net/PEAR-1.10.18
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"

The 'pear' command is now at your service at /usr/local/bin/pear

** The 'pear' command is not currently in your PATH, so you need to
** use '/usr/local/bin/pear' until you have added
** '/usr/local/bin' to your PATH environment variable.

Run it without parameters to see the available actions, try 'pear list'
to see what packages are installed, or 'pear help' for help.

For more information about PEAR, see:

  http://pear.php.net/faq.php
  http://pear.php.net/manual/

Thanks for using go-pear!
  


PHP 学習

Docker 学習 #1 コンテナの作成から実行までやってみる

公開:2026.04.10 17:57

Dockerコンテナの作成から実行までやってみる

以下記事を参考にDockerコンテナの作成から実行まで一通り試してみる。
ついに1.0がリリース! Dockerのインストールと主なコマンドの使い方

環境

Windows 11 25H2 (26200.8037)

WSLバージョン
PS C:\Users\xxx> wsl --version
WSL バージョン: 2.3.24.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.65
MSRDC バージョン: 1.2.5620
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.26200.8037

Ubuntuバージョン
xxx@xxx:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble

手順

1. まずUbuntuのDockerコンテナを実行しbashを起動
docker run -it --name ubuntu1 ubuntu /bin/bash

実行結果:
xxx@xxx:~$ docker run -it --name ubuntu1 ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
689b91d88a0f: Pull complete
b22f29e93d86: Download complete
Digest: sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103d36e876938d28895b
Status: Downloaded newer image for ubuntu:latest
    

2. Ubuntuコンテナ上でnginxをインストール
apt-get install -y nginx

でも "E: Unable to locate package nginx" と表示されインストールできない。
root@876becd7e101:/# apt-get install -y nginx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package nginx
    
これはパッケージリストが古いから、のようなのでパッケージリストを更新すればOK
apt-get update
root@876becd7e101:/# apt-get update
Get:1 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]
Get:2 http://archive.ubuntu.com/ubuntu noble InRelease [256 kB]
Get:3 http://security.ubuntu.com/ubuntu noble-security/restricted amd64 Packages [3505 kB]
Get:4 http://archive.ubuntu.com/ubuntu noble-updates InRelease [126 kB]
Get:5 http://archive.ubuntu.com/ubuntu noble-backports InRelease [126 kB]
Get:6 http://archive.ubuntu.com/ubuntu noble/multiverse amd64 Packages [331 kB]
Get:7 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Packages [1508 kB]
Get:8 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages [1989 kB]
Get:9 http://archive.ubuntu.com/ubuntu noble/restricted amd64 Packages [117 kB]
Get:10 http://archive.ubuntu.com/ubuntu noble/main amd64 Packages [1808 kB]
Get:11 http://security.ubuntu.com/ubuntu noble-security/multiverse amd64 Packages [34.8 kB]
Get:12 http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages [19.3 MB]
Get:13 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages [2377 kB]
Get:14 http://archive.ubuntu.com/ubuntu noble-updates/universe amd64 Packages [2155 kB]
Get:15 http://archive.ubuntu.com/ubuntu noble-updates/multiverse amd64 Packages [38.1 kB]
Get:16 http://archive.ubuntu.com/ubuntu noble-updates/restricted amd64 Packages [3692 kB]
Get:17 http://archive.ubuntu.com/ubuntu noble-backports/universe amd64 Packages [36.1 kB]
Get:18 http://archive.ubuntu.com/ubuntu noble-backports/main amd64 Packages [49.5 kB]
Get:19 http://archive.ubuntu.com/ubuntu noble-backports/multiverse amd64 Packages [695 B]
Fetched 37.6 MB in 4s (9283 kB/s)
Reading package lists... Done
    

再度 "apt-get install -y nginx" を実行
root@876becd7e101:/# apt-get install -y nginx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  iproute2 libatm1t64 libbpf1 libcap2-bin libelf1t64 libmnl0 libpam-cap libxtables12 nginx-common
Suggested packages:
  iproute2-doc python3:any fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:
  iproute2 libatm1t64 libbpf1 libcap2-bin libelf1t64 libmnl0 libpam-cap libxtables12 nginx nginx-common
0 upgraded, 10 newly installed, 0 to remove and 3 not upgraded.
Need to get 2026 kB of archives.
After this operation, 5799 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libelf1t64 amd64 0.190-1.1ubuntu0.1 [57.8 kB]
Get:2 http://archive.ubuntu.com/ubuntu noble/main amd64 libbpf1 amd64 1:1.3.0-2build2 [166 kB]
Get:3 http://archive.ubuntu.com/ubuntu noble/main amd64 libmnl0 amd64 1.0.5-2build1 [12.3 kB]
Get:4 http://archive.ubuntu.com/ubuntu noble/main amd64 libxtables12 amd64 1.8.10-3ubuntu2 [35.7 kB]
Get:5 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libcap2-bin amd64 1:2.66-5ubuntu2.2 [34.2 kB]
Get:6 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 iproute2 amd64 6.1.0-1ubuntu6.2 [1120 kB]
Get:7 http://archive.ubuntu.com/ubuntu noble/main amd64 libatm1t64 amd64 1:2.5.1-5.1build1 [22.9 kB]
Get:8 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libpam-cap amd64 1:2.66-5ubuntu2.2 [12.5 kB]
Get:9 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 nginx-common all 1.24.0-2ubuntu7.6 [43.5 kB]
Get:10 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 nginx amd64 1.24.0-2ubuntu7.6 [521 kB]
Fetched 2026 kB in 3s (731 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libelf1t64:amd64.
(Reading database ... 4381 files and directories currently installed.)
Preparing to unpack .../0-libelf1t64_0.190-1.1ubuntu0.1_amd64.deb ...
Unpacking libelf1t64:amd64 (0.190-1.1ubuntu0.1) ...
Selecting previously unselected package libbpf1:amd64.
Preparing to unpack .../1-libbpf1_1%3a1.3.0-2build2_amd64.deb ...
Unpacking libbpf1:amd64 (1:1.3.0-2build2) ...
Selecting previously unselected package libmnl0:amd64.
Preparing to unpack .../2-libmnl0_1.0.5-2build1_amd64.deb ...
Unpacking libmnl0:amd64 (1.0.5-2build1) ...
Selecting previously unselected package libxtables12:amd64.
Preparing to unpack .../3-libxtables12_1.8.10-3ubuntu2_amd64.deb ...
Unpacking libxtables12:amd64 (1.8.10-3ubuntu2) ...
Selecting previously unselected package libcap2-bin.
Preparing to unpack .../4-libcap2-bin_1%3a2.66-5ubuntu2.2_amd64.deb ...
Unpacking libcap2-bin (1:2.66-5ubuntu2.2) ...
Selecting previously unselected package iproute2.
Preparing to unpack .../5-iproute2_6.1.0-1ubuntu6.2_amd64.deb ...
Unpacking iproute2 (6.1.0-1ubuntu6.2) ...
Selecting previously unselected package libatm1t64:amd64.
Preparing to unpack .../6-libatm1t64_1%3a2.5.1-5.1build1_amd64.deb ...
Unpacking libatm1t64:amd64 (1:2.5.1-5.1build1) ...
Selecting previously unselected package libpam-cap:amd64.
Preparing to unpack .../7-libpam-cap_1%3a2.66-5ubuntu2.2_amd64.deb ...
Unpacking libpam-cap:amd64 (1:2.66-5ubuntu2.2) ...
Selecting previously unselected package nginx-common.
Preparing to unpack .../8-nginx-common_1.24.0-2ubuntu7.6_all.deb ...
Unpacking nginx-common (1.24.0-2ubuntu7.6) ...
Selecting previously unselected package nginx.
Preparing to unpack .../9-nginx_1.24.0-2ubuntu7.6_amd64.deb ...
Unpacking nginx (1.24.0-2ubuntu7.6) ...
Setting up libatm1t64:amd64 (1:2.5.1-5.1build1) ...
Setting up nginx-common (1.24.0-2ubuntu7.6) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 79.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.38.2 /usr/local/share/perl/5.38.2 /usr/lib/x86_64-linux-gnu/perl5/5.38 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.38 /usr/share/perl/5.38 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8.)
debconf: falling back to frontend: Teletype
Setting up libelf1t64:amd64 (0.190-1.1ubuntu0.1) ...
Setting up libcap2-bin (1:2.66-5ubuntu2.2) ...
Setting up libmnl0:amd64 (1.0.5-2build1) ...
Setting up libxtables12:amd64 (1.8.10-3ubuntu2) ...
Setting up libpam-cap:amd64 (1:2.66-5ubuntu2.2) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 79.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.38.2 /usr/local/share/perl/5.38.2 /usr/lib/x86_64-linux-gnu/perl5/5.38 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.38 /usr/share/perl/5.38 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8.)
debconf: falling back to frontend: Teletype
Setting up libbpf1:amd64 (1:1.3.0-2build2) ...
Setting up iproute2 (6.1.0-1ubuntu6.2) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 79.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.38.2 /usr/local/share/perl/5.38.2 /usr/lib/x86_64-linux-gnu/perl5/5.38 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.38 /usr/share/perl/5.38 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8.)
debconf: falling back to frontend: Teletype
Setting up nginx (1.24.0-2ubuntu7.6) ...
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Processing triggers for libc-bin (2.39-0ubuntu8.7) ...      
    
nginxをインストールしたら[CTRL]+[D]でbashプロセスを修了する。
これでDockerコンテナは停止状態となる。念のため docker ps -a で確認。
xxx@xxx:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                      PORTS     NAMES
876becd7e101   ubuntu    "/bin/bash"   5 minutes ago   Exited (0) 42 seconds ago             ubuntu1
    

3. 新しいDockerイメージを作成
nginxをインストールしたDockerコンテナ(ubuntu1)をベースに新しいDockerイメージを作成する。
作成するイメージ名は何でも良いが、ここでは"masa/nginx"とした。
docker commit ubuntu1 masa/nginx

実行結果:
xxx@xxx:~$ docker commit ubuntu1 masa/nginx
sha256:031aa9d31a4aed2c0b9ee372341e9d22a2413996a81547ef23ea5abfa222a9e8
    

docker imageを見ると新たにDockerイメージが作成されていることがわかる。
xxx@xxx:~$ docker images
REPOSITORY                         TAG       IMAGE ID       CREATED         SIZE
masa/nginx                         latest    a575318af095   4 seconds ago   146MB
ubuntu                             latest    b28307c40a80   6 days ago      78.1MB
    

4. nginxコンテナの実行
ubuntu+nginxイメージができたので、あとはこれを起動すれば簡単にWebサーバーを構築できる。
docker run -d -p 80:80 --name nginx1 masa/nginx /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

-d バックグラウンドで実行
-p 80:80 コンテナのポート80とホストのポート80をマッピング
--name nginx1 コンテナ名は "nginx1" とした。何でも良い
masa/nginx 3.で作成したDockerイメージ名
/usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf nginxの起動。-gはグローバル設定の指定で"deamon off;"でデーモン無効化→フォアグラウンドで動かす、という意味らしい。(でないとDockerでは起動できない)

実行結果:
xxx@xxx:~$ docker run -d -p 80:80 --name nginx1 masa/nginx /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
eaee932fc1a6df74332b7cf36bab1ecaadb23c694fec7a6f6f1322ca395aad2c
    

5. 動作確認
curlコマンドでlocalhost:80に接続してみるとhtmlが帰り、nginx正常に動作していることがわかる。
xxx@xxx:~$ curl localhost:80



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.


6. コンテナの停止
実行中のDockerコンテナ "nginx1" を停止する。
docker stop nginx1

停止前:
xxx@xxx:~$ docker ps
CONTAINER ID   IMAGE                                     COMMAND                  CREATED         STATUS         PORTS                                                                       NAMES
eaee932fc1a6   masa/nginx                                "/usr/sbin/nginx -g …"   5 minutes ago   Up 5 minutes   0.0.0.0:80->80/tcp, [::]:80->80/tcp                                         nginx1
    
コンテナ停止:
xxx@xxx:~$ docker stop nginx1
nginx1      
    
"docker ps" で実行中コンテナを確認。"nginx1" は表示されないので停止していることがわかる。
xxx@xxx:~$ docker ps
CONTAINER ID   IMAGE                                     COMMAND                  CREATED         STATUS        PORTS                                                                       NAMES      
    

7. コンテナ再開
停止したコンテナを再開する。
docker start ngnix1

実行結果:
xxx@xxx:~$ docker start nginx1
nginx1      
    
      xxx@xxx:~$ curl localhost:80



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.


8. コンテナの削除
最後にコンテナを停止しコンテナの削除、イメージの削除まで行う。

コンテナ停止: docker stop
xxx@xxx:~$ docker stop nginx1
nginx1      
    
コンテナ削除: docker rm
xxx@xxx:~$ docker rm nginx1
nginx1
    
コンテナイメージ削除: docker rmi
xxx@xxx:~$ docker rmi masa/nginx
Untagged: masa/nginx:latest
Deleted: sha256:b418404f73405ae1f07b311f1c008e63544099cbed5f92dc63f01a21577a1c3a
Deleted: sha256:73a461be8ff6213f197a10dc96d5563bfa2408349234280944ff13aa7aa1ae04      
    
ついでにubuntuコンテナも削除する:
xxx@xxx:~$ docker rm ubuntu1
ubuntu1
xxx@xxx:~$ docker rmi ubuntu:latest
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103d36e876938d28895b
Deleted: sha256:b28307c40a80946234f0ea8ff355d37d7802c7e9c93bd5f84002177ef70937b6
Deleted: sha256:5e732af9e7c568c9b41ecabc76ac93a58471934d5155070dfd64a9567667fd9d
    


Docker 学習

その他の記事