- 投稿日:2020-03-16T22:18:28+09:00
戻り値を変数に保存して扱う方法
最近PHP触りはじめたよーて人向け
といっても僕もまだまだ勉強中なので間違った点があればご指摘下さい、、
メモ程度です。関数て最初慣れるまで理解しにくいですよね。。。
引数とかスコープとかそんな方の助けになればとなんとなく理解しにくかったところを解説させていただきます!!!
1. function fullname($lastname, $firstname) //6行目の引数を受け取る 2. { 3. $result = $lastname.$firstname; //1行目で受け取った引数を処理して$resultへ 4. return $result; //値を変数$resultへ返す 5. } 6. $result = fullname("山田", "太郎"); //関数fullname()を呼び出し&戻り値を受け取る 7. echo "私の名前は" . $result . "です。" //表示ポイントは変数 = 関数名(引数)です!
コメントアウトで処理の流れを簡単に記しましたが、6行目のように変数 = 関数名(引数)を作ってあげて変数に値を保存してあげることです!!!
慣れるまではスコープや引数はややこしいですが、意外と単純なので頑張りましょう
- 投稿日:2020-03-16T19:18:51+09:00
Laravel6.xの日本語化パッケージ
目的
Laravel6.xの日本語化を行い、その言語リソースをパッケージ化してみる。
日本語化について
設定
config/app.php
'locale' => 'en',英語→日本語
デフォルトでは次の4種類が用意されている。
- 認証(auth.php)
- ページネーション(pagination.php)
- パスワードリセット(passwords.php)
- バリデーション(validation.php)
resources/lang/en以下に対応するphpファイルがあるので、それを翻訳してresources/lang/ja以下へ置く。
パッケージ化について
毎回翻訳するのは大変なのでパッケージ化してみる。
ServiceProviderで作成した日本語化ファイルを公開できるようにする。
public function boot() { $this->publishes([ __DIR__.'/../resources/lang' => $this->app->resourcePath('lang/'), ], 'lang-ja'); }vendor:publishコマンドで公開できるようになる。
$ php artisan vendor:publish --tag=lang-ja作成した日本語化パッケージ
ほぼGoogle翻訳なので使いつつ調整していく予定。
- 投稿日:2020-03-16T19:16:36+09:00
フロントエンドビューを作成方法
フロントエンドビュー(Frontend view)
このトピックでは、ブロック、レイアウト、テンプレートなど、Magento 2のビューについて学習します。 前のトピックでは、ルートとコントローラーを作成します。 ご存じのとおり、ページの表現を出力するためにビューが使用されます。
Magento 2では、ビューは3つのパスで作成されます。
-ブロック
- レイアウト
- テンプレート
作成したモジュールの単純なビューを構築することで、どのように作成するかを見つけます前のトピックコントローラーを作成する
まず、レイアウトファイル
.xml
を呼び出すコントローラーを作成します。Karabiner/HelloMagento2/Controller/SomethingElse/Index.php<?php namespace Karabiner\HelloMagento2\Controller\SomethingElse; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\View\Result\PageFactory; class Index extends Action { /** * @var PageFactory */ private $pageFactory; public function __construct(Context $context, PageFactory $pageFactory) { parent::__construct($context); $this->pageFactory = $pageFactory; } /** * call Karabiner/HelloMagento2/view/frontend/layout/hellomagento2_somethingelse_index layout */ public function execute() { return $this->pageFactory->create(); } }レイアウトファイル(.xml)を作成
レイアウトは、Magento 2モジュールのビューレイヤーの主要なパスです。 レイアウトファイルはXMLファイルで、
{MAGENTO_DIRECTORY}/view/{area}/layout/
フォルダーにあります。
エリアパスは、レイアウトが適用される場所を定義するfrontend
またはadminhtml
(adminダッシュボード)です。レイアウトファイルの形式は
{ルーターID} _ {コントローラー名} _ {アクション名}.xml
の形式になります。レンダリングページの場合、Magentoはレイアウトファイルをチェックしてページのハンドルを見つけ、ブロックとテンプレートをロードします。 このモジュールのレイアウトハンドルファイルを作成します。
ファイル: app/code/Karabiner/HelloMagento2/view/frontend/layout/hellomagento2_somethingelse_index.xml
app/code/Karabiner/HelloMagento2/view/frontend/layout/hellomagento2_somethingelse_index.xml<?xml version="1.0" encoding="UTF-8"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="Karabiner\HelloMagento2\Block\SomethingElse" name="hello_magento2_display" template="Karabiner_HelloMagento2::hello_world.phtml" /> </referenceContainer> </body> </page>ブロックファイルの作成
↑のファイルでは、このページのブロックとテンプレートを定義します。
class(ブロッククラス):HelloMagento2\HelloMagento2\Block\SomethingElse
ブロッククラスは、テンプレートファイルにデータを提供するクラスです。template(テンプレートファイル):Karabiner_HelloMagento2::hello_world.phtml
ファイル名には2つの部分があります。
1.Karabiner_HelloMagento2
:Karabiner/HelloMagento2/view/frontend/templates
を参照してください
2.hello_world.phtml
:上記のフォルダー内の場所は、SomethingElse/ hello_world.phtml
です。
name:これは必須属性であり、ブロックを参照として識別するために使用されますテンプレートファイルを作成する
hello_world.phtmlというテンプレートファイルを作成します
app/code/Karabiner/HelloMagento2/view/frontend/templates/hello_world.phtml
以下コードを追加してapp/code/Karabiner/HelloMagento2/view/frontend/templates/hello_world.phtml<?php /** * @var \Karabiner\HelloMagento2\Block\SomethingElse $block */ ?> <?= $block->sayHi() ?>レイアウトファイルでは、
Karabiner_HelloMagento2::hello_world.phtml
によってテンプレートを定義します。 これは、MagentoがモジュールKarabiner_HelloMagento2
のテンプレートフォルダーでファイル名hello_world.phtml
を見つけることを意味します。 モジュールのテンプレートフォルダーは、app/code/{vendor_name}/{module_name}/view/frontend/templates/
です。テンプレートファイルでは、ブロックオブジェクトに変数「$ block」を使用できます。 ご覧のとおり、Blockでメソッド
sayHi()
を呼び出します。 完了しました、レイアウトまたはphtmlを変更した後、cache:cleanコマンドラインを実行する必要があります
MAGENTO_DIRECTORYbin/magento cache:cleanもう一度このページにアクセスしてください
(http://[MAGENTO_URL]/custom_router_name/somethingelse
) and see the result.
- 投稿日:2020-03-16T18:52:10+09:00
MySQLが起動できない(動かなくなった) という地獄のエラー(ERROR! The server quit without updating PID file と Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exist)
背景
phpの学習中にmysqlをいじっていましたw
急にmysqlが起動できなくなり、エラー解消にほぼ半日躓いてしまったので、
その解決策と試したことを記事としてのせたいと思う!!mysqlでのエラー文との遭遇
エラー内容一覧
mysqlを起動を確かめる
mysql.server start Starting MySQL . ERROR! The server quit without updating PID file (/usr/local/var/mysql/ユーザーMBP.pid).意味はpidファイルを更新せずに終わったよ!ってエラー?
すいません、、、意味がわかりません(涙)pidファイルとは?
Pidファイルには、特定のプログラムのプロセスID(番号)が含まれています。たとえば、Apache HTTPDはメインプロセス番号をpidファイル(通常のテキストファイル、それ以上のもの)に書き込み、後でそこに含まれる情報を使用して停止します。 cat filename.pid | xargs killを使用して、その情報を使用して自分でプロセスを強制終了することもできるみたいです。
ググって試したこと!
①権限関係
権限確認すると「_mysql:_mysql」だったので、自分:adminに変更した。
chown -R [ユーザ名] /usr/local/var/mysqlうまくいかず。
②エラーログ確認しにいく
cd /usr/local/var/mysql ls (lsコマンドでmysqlディレクトリの中身を確認する) その中に (ユーザー)MBP.err というファイルがあるので cat (ユーザー)MBP.err (catコマンドでファイルの中身を確認) エラーログの中身に 2020-03-16 17:32:04 25993 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exist調べてみると、インストール時に mysql_install_db が実行されるが、ディレクトリがわからない状態らしい。
インストール場所とユーザ名を指定して明示的に実行すると良さそうらしいですが、、mysql_install_db --datadir=/var/lib/mysql --user=mysqlうまくいかず...
参考ページ
https://qiita.com/840_/items/06f32fecbe57c3fdf5ec③最終手段 全てをアンイストール!!
よく見るとmysql、mysql@5.6、mysql@5.7やらいっぱいmysqlが存在してしまっていたので全てアンインストール!
の前に
*実行前に
そのまま解決手順を実行してしまうと、mysqlのデータが削除されてしまいます。
以下の手順を実行し、バックアップを行ってください!!$ brew services stop mysql mysqlを一旦停止 $ cp -pr /usr/local/Cellar/mysql /適当な場所/mysql_backup これで、mysqlのデータバックアップ。brew uninstall mysql brew uninstall mysql@5.6 brew uninstall mysql@5.7まずはmysqlをアンインストール!
次にlocal配下のmysqlを全て削除する
$ rm -rf /usr/local/mysql $ rm -rf /Library/StartupItems/MYSQL $ rm -rf /Library/PreferencePanes/MySQL.prefPane $ rm -rf /Library/Receipts/mysql-.pkg $ rm -rf /usr/local/Cellar/mysql* $ rm -rf /usr/local/bin/mysql* $ rm -rf /usr/local/var/mysql* $ rm -rf /usr/local/etc/my.cnf $ rm -rf /usr/local/share/mysql* $ rm -rf /usr/local/opt/mysqlポイント!
brew uninstall mysqlでは削除できないファイル群を削除するのが大事!
残っているとアンインストールしても解消されないので、すっきり全て削除!mysqlを再インストール
brew install mysql(@__使用するmysqlバージョンを指定)mysqlコマンドをどこからでも実行できるようする
$ echo 'export PATH="/usr/local/opt/mysql/bin:$PATH"' >> ~/.bash_profile mysqlバージョンを指定している場合(mysql@5.6) $ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile $ source ~/.bash_profile mysqlのコマンドが打てるか確認する $ which mysql 以下のように表示されれば成功 /usr/local/opt/mysql/bin/mysql最後にmysqlを起動
mysqlの状態を確認するコマンドです $ mysql.server status 以下のように表示されれば成功 SUCCESS! MySQL running (29385)他にもプロセスを確認
$ ps ax | grep mysql 29714 s001 S 0:00.03 /bin/sh /usr/local/Cellar/mysql/8.0.19/bin/mysqld_safe --datadir=/usr/local/var/mysql --pid-file=/usr/local/var/mysql/ユーザMBP.pid 29825 s001 S 0:05.17 /usr/local/Cellar/mysql/8.0.19/bin/mysqld --basedir=/usr/local/Cellar/mysql/8.0.19 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/Cellar/mysql/8.0.19/lib/plugin --log-error=ユーザMBP.err --pid-file=/usr/local/var/mysql/ユーザMBP.pid 29837 s001 S+ 0:00.00 grep mysqlok問題ないですね!
参考
https://teratail.com/questions/199085これでようやく解決してくれました!
本当に強引な方法ではありますがうまくいきました!
最後に
本当によく躓くエラーなので反省をとこれからの課題として記事として残しておきます!!
- 投稿日:2020-03-16T18:19:51+09:00
Magento 2.3のDeclarative Schema
Magento 2.3のDeclarative Schema
Declarative Schemaは、Magento2.2までのPHPコードを使用したデータベーススキーマ定義作成を置き換える仕組みです。
Magento2.3から新たに導入された仕組みで、XMLファイルを使用してテーブルの構造などを定義します。Magento 2.3のDeclarative Schemaの使用する方法
Declarative Schemaの必要なファイルについてのみ説明します。
まず、フォルダ「Karabiner/Declarative/etc」内にファイル「db_schema.xml」を作成して、次のコードを記述します
db_schema.xml<?xml version="1.0" encoding="UTF-8"?> <schema xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="author_data" resource="default" engine="innodb" comment="Author Table"> <column xsi:type="smallint" name="id" padding="6" unsigned="false" nullable="false" identity="true" comment="Author ID"/> <column xsi:type="varchar" name="author_name" nullable="false" length="255" comment="Author Name"/> <column xsi:type="varchar" name="author_email" nullable="false" length="255" comment="Author Email"/> <column xsi:type="varchar" name="affliation" nullable="false" length="255" comment="Affliation"/> <column xsi:type="int" name="age" unsigned="true" nullable="true" identity="false" default="" comment="Age"/> <constraint xsi:type="primary" name="PRIMARY"> <column name="id"/> </constraint> </table> </schema>各テーブルノードは、データベース内のテーブルを表します。
テーブルノードには、次の3種類のサブノードを含めることができます。
- Column
- Constraint
- Index
setup:upgrade
コマンドを実行すると、テーブル「author_data」が作成されます新しい列を追加
既存のテーブルに新しい列を追加する場合は、
db_schema.xml
に新しい列ノード(<column>
)を追加する必要があります。setup:upgrade
コマンドを実行すると、新しい列が追加されます。db_schema.xml<column xsi:type="int" name="new_column" unsigned="true" nullable="true" identity="false" default="" comment="New column" />既存の列を削除
既存の列を削除する場合は、テーブルノード内の列ノード(
<column>
)を削除するか、disabled
アトリビュートをtrue
に設定する必要があります。db_schema.xml<column xsi:type="int" name="age" unsigned="true" nullable="true" identity="false" default="" comment="Age" disabled=”true” />しかし、アップグレードコマンドを実行する前に、次のコマンドを実行してスキーマを
db_whitelist_schema.json
ファイルに追加する必要があります。php bin/magento setup:db-declaration:generate-whitelist --module-name=Karabiner_Declarative
Karabiner_Declarative
はモジュール名です。 そこでモジュール名を指定する必要があります。
setup:upgrade
コマンドを実行すると、列が削除されます。列タイプを変更し、そのtypeアトリビュートをint、varchar、textなどに変更できます。
列の名前を変更
列の名前を変更するには、まず不要な列を削除する必要があります。 別の列を追加します。 その列のデータを新しく作成したものに移行する必要があります。これを行うには、古い列からデータを移行するアトリビュートonCreateを設定する必要があります。
author_email列の名前を「email」に変更する場合は、author_email列を削除して新しい列を追加します。db_schema.xml<column xsi:type="varchar" name="email" onCreate="migrateDataFrom(author_email)" on_update="false" nullable="false" default="" comment="Author Email"/> <column xsi:type="varchar" name="author_email" unsigned="true" nullable="true" identity="false" default="" comment="Email" disabled=”true” />削除された列のデータで新しい列「email」が作成されます。
テーブルをドロップ
テーブルを削除するには、テーブルノード全体を「db_schema.xml」から削除するか、「disabled」アトリビュートを「true」に設定します。
db_schema.xml<?xml version="1.0" encoding="UTF-8"?> <schema xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="author_data" resource="default" engine="innodb" comment="Author Table" disabled=”true”> .... </table> </schema>
- 投稿日:2020-03-16T17:23:12+09:00
Declarative Schema in Magento 2.3
Declarative Schema in Magento 2.3
Magento has introduced a new feature called Declarative Schema which aims to simplify the Magento installation and upgrade processes. This new concept will allow a developer to get away from writing updates for each new version in favour of declaring the final result that the developer wants to achieve.
How to use Declarative Schema in Magento 2.3
we will only discuss file required for a Declarative Schema.
Firstly create a file
db_schema.xml
inside the folderKarabiner/Declarative/etc
and write the following codedb_schema.xml<?xml version="1.0" encoding="UTF-8"?> <schema xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="author_data" resource="default" engine="innodb" comment="Author Table"> <column xsi:type="smallint" name="id" padding="6" unsigned="false" nullable="false" identity="true" comment="Author ID"/> <column xsi:type="varchar" name="author_name" nullable="false" length="255" comment="Author Name"/> <column xsi:type="varchar" name="author_email" nullable="false" length="255" comment="Author Email"/> <column xsi:type="varchar" name="affliation" nullable="false" length="255" comment="Affliation"/> <column xsi:type="int" name="age" unsigned="true" nullable="true" identity="false" default="" comment="Age"/> <constraint xsi:type="primary" name="PRIMARY"> <column name="id"/> </constraint> </table> </schema>Each table node represents a table in the database.
A table node can contain three types of subnodes:
- Column
- Constraint
- Index
So when you run
setup:upgrade
command then it will create the table “author_data”Adding New Column
If you want to add a new column to the existing table then you need to add a new column node in db_schema.xml and on running upgrade command it will add the new column.
db_schema.xml<column xsi:type="int" name="new_column" unsigned="true" nullable="true" identity="false" default="" comment="New column" />Remove Existing Column
Now if you want to remove the existing column then you either need to remove the column node (< column >) inside the table node or you can set the
disabled
attribute totrue
.db_schema.xml<column xsi:type="int" name="age" unsigned="true" nullable="true" identity="false" default="" comment="Age" disabled=”true” />But before running the upgrade command you need to add your schema to db_whitelist_schema.json file by running the following command-
php bin/magento setup:db-declaration:generate-whitelist --module-name=Karabiner_Declarative
Karabiner_Declarative
is a module name. You need to specify your module name there.Now on running
setup:upgrade
command, it will remove the column.Changing the column type
You can change the column type, changing its type attribute to int, varchar, text etc.Renaming a column
To rename a column you need to first remove the one you don’t want and add another column with your desired name. Now you need to migrate that column data into a newly created one, to do this you need to set an attribute on Create which will migrate data from the old column.
If we want to rename the author_email column to just email, we will remove the author column and add a new one.db_schema.xml<column xsi:type="varchar" name="email" onCreate="migrateDataFrom(author_email)" on_update="false" nullable="false" default="" comment="Author Email"/> <column xsi:type="int" name="email" unsigned="true" nullable="true" identity="false" default="" comment="Email" disabled=”true” />So this will create a new column ‘email’ with data from the removed column.
Drop a Table
To drop a table, either remove the entire table node from
db_schema.xml
or set thedisabled
attribute totrue
.db_schema.xml<?xml version="1.0" encoding="UTF-8"?> <schema xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="author_data" resource="default" engine="innodb" comment="Author Table" disabled=”true”> .... </table> </schema>
- 投稿日:2020-03-16T16:10:09+09:00
PHPエクステンションをCMakeする
PHP extensionをCMakeを使ってビルドする
構成
sample/ CMakeLists.txt config.cmake config.h.in php_sample.h sample.c test.php各ファイル
CMakeLists.txtcmake_minimum_required(VERSION 3.5.1) project(sample-ext) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_FLAGS "-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DPHP_ATOM_INC -DHAVE_CONFIG_H -O3 -funroll-loops") execute_process(COMMAND "php-config" "--prefix" OUTPUT_VARIABLE PHP_BASE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "php-config" "--include-dir" OUTPUT_VARIABLE PHP_INCLUDE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "php-config" "--extension-dir" OUTPUT_VARIABLE EXTENSION_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) set(COMPILE_DL_SAMPLE 1) set(HAVE_SAMPLE 1) include(config.cmake) include_directories( "${PHP_INCLUDE_PATH}" "${PHP_INCLUDE_PATH}/main" "${PHP_INCLUDE_PATH}/TSRM" "${PHP_INCLUDE_PATH}/Zend" "${PHP_INCLUDE_PATH}/ext" "${PHP_INCLUDE_PATH}/ext/date/lib" ${CMAKE_BINARY_DIR}) add_library(sample-shared SHARED ${CMAKE_CURRENT_SOURCE_DIR}/sample.c) set_target_properties(sample-shared PROPERTIES LINK_FLAGS "-Wl,-rpath,${PHP_BASE_PATH}/lib") set_target_properties(sample-shared PROPERTIES PREFIX "" OUTPUT_NAME sample) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sample.so DESTINATION ${EXTENSION_DIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)config.cmakefind_path(DLFCN_H_PATH dlfcn.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(INTTYPES_H_PATH inttypes.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(MEMORY_H_PATH memory.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(STDINT_H_PATH stdint.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(STDLIB_H_PATH stdlib.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(STRINGS_H_PATH strings.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(STRING_H_PATH string.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(SYS_STAT_H_PATH sys/stat.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(SYS_TYPES_H_PATH sys/types.h PATHS /usr /usr/local PATH_SUFFIXES include) find_path(UNISTD_H_PATH unistd.h PATHS /usr /usr/local PATH_SUFFIXES include) if (DLFCN_H_PATH) set(HAVE_DLFCN_H 1) endif (DLFCN_H_PATH) if (INTTYPES_H_PATH) set(HAVE_INTTYPES_H 1) endif (INTTYPES_H_PATH) if (MEMORY_H_PATH) set(HAVE_MEMORY_H 1) endif (MEMORY_H_PATH) if (STDINT_H_PATH) set(HAVE_STDINT_H 1) endif (STDINT_H_PATH) if (STDLIB_H_PATH) set(HAVE_STDLIB_H 1) endif (STDLIB_H_PATH) if (STRINGS_H_PATH) set(HAVE_STRINGS_H 1) endif (STRINGS_H_PATH) if (STRING_H_PATH) set(HAVE_STRING_H 1) endif (STRING_H_PATH) if (SYS_STAT_H_PATH) set(HAVE_SYS_STAT_H 1) endif (SYS_STAT_H_PATH) if (SYS_TYPES_H_PATH) set(HAVE_SYS_TYPES_H 1) endif (SYS_TYPES_H_PATH) if (UNISTD_H_PATH) set(HAVE_UNISTD_H 1) endif (UNISTD_H_PATH) set(PACKAGE_BUGREPORT "") set(PACKAGE_NAME "") set(PACKAGE_STRING "") set(PACKAGE_TARNAME "") set(PACKAGE_URL "") set(PACKAGE_VERSION "") if (DLFCN_H_PATH AND INTTYPES_H_PATH AND MEMORY_H_PATH AND STDINT_H_PATH AND STDLIB_H_PATH AND STRINGS_H_PATH AND STRING_H_PATH AND SYS_STAT_H_PATH AND SYS_TYPES_H_PATH AND UNISTD_H_PATH) set(STDC_HEADERS 1) endif (DLFCN_H_PATH AND INTTYPES_H_PATH AND MEMORY_H_PATH AND STDINT_H_PATH AND STDLIB_H_PATH AND STRINGS_H_PATH AND STRING_H_PATH AND SYS_STAT_H_PATH AND SYS_TYPES_H_PATH AND UNISTD_H_PATH) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_BINARY_DIR}/config.h)config.h.in#cmakedefine COMPILE_DL_SAMPLE @COMPILE_DL_SAMPLE@ #cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@ #cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@ #cmakedefine HAVE_MEMORY_H @HAVE_MEMORY_H@ #cmakedefine HAVE_SAMPLE @HAVE_SAMPLE@ #cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@ #cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@ #cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@ #cmakedefine HAVE_STRING_H @HAVE_STRING_H@ #cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ #cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ #cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ #cmakedefine NO_MINUS_C_MINUS_O @NO_MINUS_C_MINUS_O@ #define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" #define PACKAGE_NAME "@PACKAGE_NAME@" #define PACKAGE_STRING "@PACKAGE_STRING@" #define PACKAGE_TARNAME "@PACKAGE_TARNAME@" #define PACKAGE_URL "@PACKAGE_URL@" #define PACKAGE_VERSION "@PACKAGE_VERSION@" #cmakedefine STDC_HEADERS @STDC_HEADERS@
上記は
phpize
と./configure
が担当している部分ですが多分こんな感じです。
これがないとエラーになったので、config.h
はコピペした方が良いかもしれません。php_sample.h#ifndef PHP_SAMPLE_H # define PHP_SAMPLE_H extern zend_module_entry sample_module_entry; # define phpext_sample_ptr &sample_module_entry # define PHP_SAMPLE_VERSION "0.1.0" # if defined(ZTS) && defined(COMPILE_DL_SAMPLE) ZEND_TSRMLS_CACHE_EXTERN() # endif #endif /* PHP_SAMPLE_H */sample.c#ifdef HAVE_CONFIG_H # include "config.h" #endif #include "php.h" #include "ext/standard/info.h" #include "php_sample.h" /* For compatibility with older PHP versions */ #ifndef ZEND_PARSE_PARAMETERS_NONE #define ZEND_PARSE_PARAMETERS_NONE() \ ZEND_PARSE_PARAMETERS_START(0, 0) \ ZEND_PARSE_PARAMETERS_END() #endif /* {{{ void sample_test1() */ PHP_FUNCTION(sample_test1) { ZEND_PARSE_PARAMETERS_NONE(); php_printf("The extension %s is loaded and working!\r\n", "sample"); } /* }}} */ /* {{{ string sample_test2( [ string $var ] ) */ PHP_FUNCTION(sample_test2) { char *var = "World"; size_t var_len = sizeof("World") - 1; zend_string *retval; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL Z_PARAM_STRING(var, var_len) ZEND_PARSE_PARAMETERS_END(); retval = strpprintf(0, "Hello %s", var); RETURN_STR(retval); } /* }}}*/ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(sample) { #if defined(ZTS) && defined(COMPILE_DL_SAMPLE) ZEND_TSRMLS_CACHE_UPDATE(); #endif return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(sample) { php_info_print_table_start(); php_info_print_table_header(2, "sample support", "enabled"); php_info_print_table_end(); } /* }}} */ /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_sample_test1, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_sample_test2, 0) ZEND_ARG_INFO(0, str) ZEND_END_ARG_INFO() /* }}} */ /* {{{ sample_functions[] */ static const zend_function_entry sample_functions[] = { PHP_FE(sample_test1, arginfo_sample_test1) PHP_FE(sample_test2, arginfo_sample_test2) PHP_FE_END }; /* }}} */ /* {{{ sample_module_entry */ zend_module_entry sample_module_entry = { STANDARD_MODULE_HEADER, "sample", /* Extension name */ sample_functions, /* zend_function_entry */ NULL, /* PHP_MINIT - Module initialization */ NULL, /* PHP_MSHUTDOWN - Module shutdown */ PHP_RINIT(sample), /* PHP_RINIT - Request initialization */ NULL, /* PHP_RSHUTDOWN - Request shutdown */ PHP_MINFO(sample), /* PHP_MINFO - Module info */ PHP_SAMPLE_VERSION, /* Version */ STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_SAMPLE # ifdef ZTS ZEND_TSRMLS_CACHE_DEFINE() # endif ZEND_GET_MODULE(sample) #endifこちらはスケルトンそのままです。
test.php<?php sample_test1();ビルド
$ mkdir build $ cd build $ cmake .. $ make -j動作確認
$ php -d extension=build/sample.so -f test.php The extension sample is loaded and working!phpize
sample.pb.cc
のようなファイル名だとIFS
コマンドで分割している箇所でおかしくなるのでCMakeのサンプルがあったので調整してみました。
動作確認の引数をいつも忘れるので備忘録です。
- 投稿日:2020-03-16T15:48:57+09:00
WordPress検証コード
概要
WordPressのテーマ・プラグインの検証をするときによく使うコードをまとめます。
開発よりもむしろ全体的なチューニングでよく使うものです。ログ出力
ログをファイルに書き出す。
/wp-content/debug.log
にログが書き出される。これを
wp-config.php
に書くdefine( 'WP_DEBUG', true ); if ( WP_DEBUG ) { define( 'WP_DEBUG_LOG', true ); define( 'WP_DEBUG_DISPLAY', true ); @ini_set( 'display_errors', 1 ); define( 'SAVEQUERIES', true ); }ログ出力
error_log('test message');Hook
掛かっているフックを調べる
現状どのようなフックが掛かっているかを確認する。
ある程度は何がどんなフックをかけているか把握できる。add_action('wp_footer', function(){ global $wp_filter; echo "<pre>"; var_dump($wp_filter['wp_footer']); echo "</pre>"; });どのタイミングで起こるのかを確認
WordPressの基本的なアクションフックが始まるごとにログを出力する。結構力技。
テーマのfunctions.php上ではロードが遅いので、プラグインから動かすのがおすすめ。
add_action('muplugins_loaded',function(){error_log('[hook] muplugins_loaded');},0); add_action('registered_taxonomy',function(){error_log('[hook] registered_taxonomy');},0); add_action('registered_post_type',function(){error_log('[hook] registered_post_type');},0); add_action('plugins_loaded',function(){error_log('[hook] plugins_loaded');},0); add_action('sanitize_comment_cookies',function(){error_log('[hook] sanitize_comment_cookies');},0); add_action('setup_theme',function(){error_log('[hook] setup_theme');},0); add_action('load_textdomain',function(){error_log('[hook] load_textdomain');},0); add_action('after_setup_theme',function(){error_log('[hook] after_setup_theme');},0); add_action('auth_cookie_malformed',function(){error_log('[hook] auth_cookie_malformed');},0); add_action('auth_cookie_valid',function(){error_log('[hook] auth_cookie_valid');},0); add_action('set_current_user',function(){error_log('[hook] set_current_user');},0); add_action('init',function(){error_log('[hook] init');},0); add_action('register_sidebar',function(){error_log('[hook] register_sidebar');},0); add_action('wp_register_sidebar_widget',function(){error_log('[hook] wp_register_sidebar_widget');},0); add_action('wp_default_scripts',function(){error_log('[hook] wp_default_scripts');},0); add_action('wp_default_styles',function(){error_log('[hook] wp_default_styles');},0); add_action('admin_bar_init',function(){error_log('[hook] admin_bar_init');},0); add_action('add_admin_bar_menus',function(){error_log('[hook] add_admin_bar_menus');},0); add_action('wp_loaded',function(){error_log('[hook] wp_loaded');},0); add_action('parse_request',function(){error_log('[hook] parse_request');},0); add_action('send_headers',function(){error_log('[hook] send_headers');},0); add_action('parse_query',function(){error_log('[hook] parse_query');},0); add_action('pre_get_posts',function(){error_log('[hook] pre_get_posts');},0); add_action('posts_selection',function(){error_log('[hook] posts_selection');},0); add_action('wp',function(){error_log('[hook] wp');},0); add_action('template_redirect',function(){error_log('[hook] template_redirect');},0); add_action('get_header',function(){error_log('[hook] get_header');},0); add_action('wp_enqueue_scripts',function(){error_log('[hook] wp_enqueue_scripts');},0); add_action('twentyeleven_enqueue_color_scheme',function(){error_log('[hook] twentyeleven_enqueue_color_scheme');},0); add_action('wp_head',function(){error_log('[hook] wp_head');},0); add_action('wp_print_styles',function(){error_log('[hook] wp_print_styles');},0); add_action('wp_print_scripts',function(){error_log('[hook] wp_print_scripts');},0); add_action('get_search_form',function(){error_log('[hook] get_search_form');},0); add_action('loop_start',function(){error_log('[hook] loop_start');},0); add_action('the_post',function(){error_log('[hook] the_post');},0); add_action('get_template_part_content',function(){error_log('[hook] get_template_part_content');},0); add_action('loop_end',function(){error_log('[hook] loop_end');},0); add_action('get_sidebar',function(){error_log('[hook] get_sidebar');},0); add_action('dynamic_sidebar',function(){error_log('[hook] dynamic_sidebar');},0); add_action('get_search_form',function(){error_log('[hook] get_search_form');},0); add_action('pre_get_comments',function(){error_log('[hook] pre_get_comments');},0); add_action('wp_meta',function(){error_log('[hook] wp_meta');},0); add_action('get_footer',function(){error_log('[hook] get_footer');},0); add_action('get_sidebar',function(){error_log('[hook] get_sidebar');},0); add_action('twentyeleven_credits',function(){error_log('[hook] twentyeleven_credits');},0); add_action('wp_footer',function(){error_log('[hook] wp_footer');},0); add_action('wp_print_footer_scripts',function(){error_log('[hook] wp_print_footer_scripts');},0); add_action('admin_bar_menu',function(){error_log('[hook] admin_bar_menu');},0); add_action('wp_before_admin_bar_render',function(){error_log('[hook] wp_before_admin_bar_render');},0); add_action('wp_after_admin_bar_render',function(){error_log('[hook] wp_after_admin_bar_render');},0); add_action('shutdown',function(){error_log('[hook] shutdown');},0);スタイル・スクリプト
キューされているスクリプト一覧を見る
add_action( 'wp_print_scripts', function() { echo "<pre>"; var_dump(wp_scripts()->queue); echo "</pre>"; }, 0);スタイル
add_action( 'wp_print_scripts', function() { echo "<pre>"; var_dump(wp_styles()->queue); echo "</pre>"; }, 100);
- 投稿日:2020-03-16T15:21:11+09:00
Laradockをやる時にコンテナがdocker-composeでもなかなか立ち上がってくれなかった話
Laradockを使っての環境構築にチャレンジしてみました。
Windows10 homeを使っているので、Docker for Desktopは使えず、
かつInsider Previewには切り替えたくないなと思いましたので、
Docker Toolboxをインストール!https://docs.docker.com/toolbox/toolbox_install_windows/
こちらリンクですが、入ってみても分かる通り、非常にわかりにくいUIですが頑張ってインストールしましょう。
その際に、gitとvirtual boxがインストールしますかと選択肢がでますが、
すでにインストールしている人はダブルと不具合になるのでチェックは外しておきましょう。インストール完了するとDocker Quickstart Terminalgが使えるのでクリックして起動。
初回はけっこう時間がかかります。
終了したら、おなじみのクジラのAAとIPアドレスが採番されて完了です。実際にVirtual Boxを開いてみてみると、「default」というボックスが立ち上がっているのが見てわかります。
その後、任意のターミナル(せっかく開いているのでDocker Quickstart Terminalでよいかと)で
$ docker --versionと入力するとバージョンが返ってきたらインストール完了です。
続いて任意のディレクトリ(僕はいつもCフォルダ直下に作っています)で
/c$ mkdir docker-workspaceと打って作業用フォルダを作りましょう。
/c$ cd docker-workspaceでそこに移動して、Laradockをインストールします。
docker-workspace$ git clone https://github.com/Laradock/laradock.git $ ls > laradock $ cd laradock次にenvファイルの名前を書き換えます。
laradock$ cp env-example .envここまでできたら、いよいよコンテナを立ち上げていきます。
laradock$ docker-compose up -d nginx mysql phpmyadmin workspaceこちらもプロセスにかなりの時間が初回はかかります。
そして、ほとんどの方は問題なく終了するかと思いますが、
私の場合は、こんなエラーがでてきました。Starting phpmyadmin ... error ERROR: for phpmyadmin Cannot start service phpmyadmin: driver failed programming external coStarting phpmyadmin ... error 006): Bind for 0.0.0.0:8080 failed: port is already allocated ERROR: for workspaceCannot start service workspace: driver failed programming external connectivity on endpoint workspace(xxxxxxxxx): Bind for 0.0.0.0:8080 failed: port is already allocatedどうやら、ポートが被っている??
一旦、再起動してみたり、コンテナを削除して作り直しても無駄なうえ、
lsofコマンドができず、起動しているファイルをkillすることもできなかったので、
.envファイルを編集することにしました。.env### WORKSPACE ############################################# WORKSPACE_COMPOSER_GLOBAL_INSTALL=true WORKSPACE_COMPOSER_AUTH=false WORKSPACE_COMPOSER_REPO_PACKAGIST= WORKSPACE_NVM_NODEJS_ORG_MIRROR= WORKSPACE_INSTALL_NODE=true WORKSPACE_NODE_VERSION=node WORKSPACE_NPM_REGISTRY= WORKSPACE_INSTALL_YARN=true WORKSPACE_YARN_VERSION=latest WORKSPACE_INSTALL_NPM_GULP=true WORKSPACE_INSTALL_NPM_BOWER=false WORKSPACE_INSTALL_NPM_VUE_CLI=true WORKSPACE_INSTALL_NPM_ANGULAR_CLI=false WORKSPACE_INSTALL_PHPREDIS=true WORKSPACE_INSTALL_WORKSPACE_SSH=false WORKSPACE_INSTALL_SUBVERSION=false WORKSPACE_INSTALL_BZ2=false WORKSPACE_INSTALL_GMP=false WORKSPACE_INSTALL_XDEBUG=false WORKSPACE_INSTALL_PCOV=false WORKSPACE_INSTALL_PHPDBG=false WORKSPACE_INSTALL_SSH2=false WORKSPACE_INSTALL_LDAP=false WORKSPACE_INSTALL_SOAP=false WORKSPACE_INSTALL_XSL=false WORKSPACE_INSTALL_SMB=false WORKSPACE_INSTALL_IMAP=false WORKSPACE_INSTALL_MONGO=false WORKSPACE_INSTALL_AMQP=false WORKSPACE_INSTALL_CASSANDRA=false WORKSPACE_INSTALL_GEARMAN=false WORKSPACE_INSTALL_MSSQL=false WORKSPACE_INSTALL_DRUSH=false WORKSPACE_DRUSH_VERSION=8.1.17 WORKSPACE_INSTALL_DRUPAL_CONSOLE=false WORKSPACE_INSTALL_WP_CLI=false WORKSPACE_INSTALL_AEROSPIKE=false WORKSPACE_INSTALL_OCI8=false WORKSPACE_INSTALL_V8JS=false WORKSPACE_INSTALL_LARAVEL_ENVOY=false WORKSPACE_INSTALL_LARAVEL_INSTALLER=false WORKSPACE_INSTALL_DEPLOYER=false WORKSPACE_INSTALL_PRESTISSIMO=false WORKSPACE_INSTALL_LINUXBREW=false WORKSPACE_INSTALL_MC=false WORKSPACE_INSTALL_SYMFONY=false WORKSPACE_INSTALL_PYTHON=false WORKSPACE_INSTALL_POWERLINE=false WORKSPACE_INSTALL_SUPERVISOR=false WORKSPACE_INSTALL_IMAGE_OPTIMIZERS=false WORKSPACE_INSTALL_IMAGEMAGICK=false WORKSPACE_INSTALL_TERRAFORM=false WORKSPACE_INSTALL_DUSK_DEPS=false WORKSPACE_INSTALL_PG_CLIENT=false WORKSPACE_INSTALL_PHALCON=false WORKSPACE_INSTALL_SWOOLE=false WORKSPACE_INSTALL_TAINT=false WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false WORKSPACE_INSTALL_MYSQL_CLIENT=false WORKSPACE_INSTALL_PING=false WORKSPACE_INSTALL_SSHPASS=false WORKSPACE_INSTALL_INOTIFY=false WORKSPACE_INSTALL_FSWATCH=false WORKSPACE_INSTALL_YAML=false WORKSPACE_INSTALL_MAILPARSE=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.42 WORKSPACE_TIMEZONE=UTC WORKSPACE_SSH_PORT=2222 WORKSPACE_INSTALL_FFMPEG=false WORKSPACE_INSTALL_WKHTMLTOPDF=false WORKSPACE_INSTALL_GNU_PARALLEL=false WORKSPACE_INSTALL_AST=true WORKSPACE_AST_VERSION=1.0.3 WORKSPACE_VUE_CLI_SERVE_HOST_PORT=8008 #ここ、8080になってたので適当な番号に書き換えました! WORKSPACE_VUE_CLI_UI_HOST_PORT=8001 WORKSPACE_INSTALL_GIT_PROMPT=falseこれでコマンドをやり直したらできました!!
docker-compose upとだけやってしまうと、容量不足になってしまい、
ERROR: Service 'web' failed to build: failed to copy files: failed to copy directory: Error processing tar file(exit status 1): open /node_modules/hosted-git-info/CHANGELOG.md: no space left on deviceみたいな感じでエラーになってしまうので、立ち上げるコンテナを-dで指定しましょう。
立ち上げた後は、laradock$ docker-compose exec workspace bashと打ってワークスペースに接続します。ディレクトリがroot@var/wwwみたいな感じに変わったら成功。いつもやるようにプロジェクトをコマンドを打って作りましょう。
laradock$ composer create-project --prefer-dist laravel/laravel #アプリ名またこれで少しの間完了するまで放置します。
root@var/www$ ls >laradock #アプリ名できたらexitで接続を終了します。
laradock$ cd nginx/sites/最後にnginxの設定ファイルを編集します。
laradock/nginx/sites$ cp default.conf default.conf.backup $ cp laravel.conf.example default.conf $ vim default.confdefalut.confserver { listen 80; listen [::]:80; # For https # listen 443 ssl; # listen [::]:443 ssl ipv6only=on; # ssl_certificate /etc/nginx/ssl/default.crt; # ssl_certificate_key /etc/nginx/ssl/default.key; server_name laravel.test; root /var/www/laravel/#ここにアプリ名を入れる!/public; index index.php index.html index.htm;laradockに戻って $docker-compose restartをして、
Docker Quickstart Terminal起動時に出るIPアドレスをブラウザで入力すると、
Laravelトップページがでます。これで、環境構築は完了です!
- 投稿日:2020-03-16T15:09:14+09:00
AWSで作ったLaravelアプリケーションをXserverにデプロイする
はじめに
タイトル通りですが、LaravelアプリケーションのデプロイをXserverで試してみました。
AWSでアプリケーションは作成したのですが、
XAMPPで作成した方も以下のやり方でできると思います。まとめ
さっそくですがやり方を以下にまとめました。
※XAMPPでアプリケーションを作成した方は⑥以降を参考にしていただければと思います。
①AWSでLaravelアプリケーションを作成。
②作成したアプリケーションのフォルダをダウンロードしてXAMPP環境下(htdocs内)に保存する。
③XAMPPでphpMyAdminを起動。アプリケーション用のDB(DB名:laravel)を作成する。
④.envをXAMPP環境下でDBが使えるようにに編集。
.envDB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD=⑤コマンドプロンプトで同フォルダに移動してテーブル作成
$ cd 作成したアプリのフォルダ $ php artisan migrate//このコマンドでテーブルが作成されます。⑥FTP(FileZillaを使用しました)で転送したいドメイン内のpublic_htmlへ作成したアプリのpublic内のファイルをすべて転送
⑦publicフォルダ以外のファイルをまとめて新しく作ったフォルダに転送(public_htmlと同じ階層下)
⑧public_htmlに転送したindex.phpのrequire先を新しく作ったフォルダ先に変更
index.phprequire __DIR__.'/../laraveltest/vendor/autoload.php';//28行目 ~~ $app = require_once __DIR__.'/../laraveltest/bootstrap/app.php';//38行目⑨XAMPP環境下のphpMyAdminで同アプリ用に作ったテーブルをエクスポート(.sqlファイル)
⑩先ほどエクスポートしたsqlファイルをXserver環境下のphpMyAdminにインポートしてテーブル作成
⑪転送した.envを以下のように編集して保存
.envAPP_URL=http://独自ドメイン/ DB_connection=mysql DB_HOST=自身のサーバ名.xserver.jp DB_PORT=3306 DB_DATABASE=自身のデータベース名 DB_USERNAME=自身のユーザー名 DB_PASSWORD=自身で設定したパスワード⑫対象のドメインへアクセスして問題ないか確認。
実際にデプロイしたサイトは以下になります。
よければ覗いてみてください◎
https://craftbeers.site参考
参考にさせていただいた記事は以下です。
https://qiita.com/hitotch/items/5c8c2858c883e69cd507最後に
完全に個人的備忘録です。
もしかしたらかなり遠回りな方法でデプロイしているかもしれませんので、
他にも良い方法がありましたら教えていただけますと幸いです。
また、初投稿で書き方もあまりわからなかったのでかなり雑な記事になってしまいました。。。
- 投稿日:2020-03-16T12:50:11+09:00
未定義の場合実行しないforeachを、なるべくシンプルに書いてみる
目的
- PHP Warning: Invalid argument supplied for foreach() を起こさない
- 予め空配列を定義するのもなんか嫌
- でも定義されているときはforeachを実行してほしい
対策
// $array をstring型の配列と仮定します foreach($array as $key => $value){ echo $value; } // => PHP Warning: Invalid argument supplied for foreach() // 対策 if(isset($array)) foreach($array as $key => $value){ echo $value; } // => エラーも起きず、何も出力されない $array = ['a', 'b', 'c']; // $array をstring型の配列と仮定します if(isset($array)) foreach($array as $key => $value){ echo $value; } // => abc課題点
- そもそも未定義かもしれない変数を使う構造の是非
- isset()関数の仕様上、NULLと未定義を区別できない(らしい)
アルバイト中、if文とforeach文を1行にまとめられるのか気になったので調べてみました。
「こういうのもあるよ!」とか「やめたほうがいいよ!」などありましたらコメントお願いします。?♂️(お手柔らかに)
- 投稿日:2020-03-16T11:37:07+09:00
swagger-php �で書く Annotation テンプレ3種
この記事は、温かみのある手作業で swagger-php の annotation を書かなければいけない人向けに、コピペで使えるannotationを提供する目的でまとめます。
単なる key value 表現のannotation
出力例
{ "id": "1", "name": "サンプル太郎", "email": "example@hoge.com", "created_at": "2006-04-13T14:12:53+09:00" }annotation
/** * @OA\Get( * tags={"Common"}, * path="/api/user", * @OA\Response( * response="200", * description="success", * @OA\JsonContent(ref="#/components/schemas/user_responder") * ), * @OA\Response( * response="204", * description="there is no authorized user", * @OA\JsonContent(ref="#/components/schemas/204_no_content") * ) * ) */tags は swagger-ui で見るときに整理されて見えるので便利のためにつけてます。
Response については別のところで定義した schema を参照するようにして、リクエストとレスポンスを別々に定義できるようにしています。以下は schema の書き方です。
まずはシンプルな方式から。/** * @OA\Schema( * schema="user_responder", * required={"id", "name", "email", "created_at"}, * @OA\Property( * property="id", * type="integer", * description="ユーザID", * example="1" * ), * @OA\Property( * property="name", * type="string", * description="ユーザの名前", * example="サンプル太郎" * ), * ~その他フィールド略。追加する場合にはカンマを忘れがちなのでお気をつけて~ * ) */クラスやフィールドに寄り添った書き方。分解して書くことができます。
/** * @OA\Schema( * schema="user_responder", * required={"id", "name"} * ) */ class UserResponder extends BaseResponder { /** * @OA\Property( * property="id", * type="integer", * description="ユーザID", * example="1" * ), */ private $id; /** * @OA\Property( * property="name", * type="string", * description="ユーザの名前", * example="サンプル太郎" * ), */ private $name;required はそれぞれのプロパティに書くのではなくて、schemaに定義します。
配列を含むannotation
出力例
{ "news": [ { "id": 5, "title": "Synergy Night Fever 2019 ──国内ベンチャーシーンを牽引する経営者3名とM&Aについて語る イベントレポート", "created_at": "2019-08-26T11:01:38+09:00" }, { "id": 4, "title": "テスト", "created_at": "2019-07-31T10:41:21+09:00" }, ] }annotation
/** * @OA\Get( * tags={"Media"}, * path="/api/news", * @OA\Response( * response="200", * description="success", * @OA\JsonContent(ref="#/components/schemas/news_list_responder") * ), * ) */呼び出される schema は以下のようになります。
/** * @OA\Schema( * schema="news_summary", * required={"id", "title", "created_at"}, * @OA\Property(property="id", type="integer", example=1), * @OA\Property(property="title", type="string", example="タイトル"), * @OA\Property(property="created_at", type="string", example="2020-01-17T11:25:28+09:00"), * ) */ /** * @OA\Schema( * schema="news_list_responder", * ) */ class NewsListResponder extends BaseResponder { /** * @OA\Property( * property="news", * type="array", * @OA\Items( * ref="#/components/schemas/news_summary" * ), * ) */ private $news;ちょっと複雑ですが、要するに、まずは
list
の schema を呼び出して、property が配列なので、さらに別のschemaを呼び出しています。
array type の property の中で schema を定義せず全て子供の property を定義することも試したのですが、それは動きませんでした。ちょっとハマりどころ。キーに対してオブジェクトを指定するannotation
出力例
{ "number_of_people_options": { "1": "~5人", "2": "5~10人" }, "headquarter_location_options": { "1": "北海道", "2": "青森県" } }annotation
/** * @OA\Get( * tags={"Common"}, * path="/api/options/info", * @OA\Response( * response="200", * description="success", * @OA\JsonContent(ref="#/components/schemas/info_options_responder") * ), * ) *//** * @OA\Schema( * schema="info_options_responder", * type="object", * required={"number_of_people_options", "headquarter_location_options"} * ) */ class InfoOptionsResponder extends BaseResponder { /** * @OA\Property( * property="number_of_people_options", * type="object", * example={1: "~5人", 2: "5~10人"} * ), */ private $numberOfPeopleOptions; /** * @OA\Property( * property="headquarter_location_options", * type="object", * example={1: "北海道", 2: "青森県"} * ), */ private $headquarterLocationOptions;schema においては object type を使用します。property の object の key value が固定であればさらに定義できますが、このケースのように固定じゃない場合には array が使えるかもしれません(この形は本運用でまだ使えていないので今後の宿題にして、かけたら更新します)。
終わりに
書き慣れるまでなかなか辛いです。慣れてしまうとパターンも少ないので案外サクサクかけます。
このannotationを使ったdocumentから実際のAPIレスポンスをテストできるのですが、それについては他の記事で書こうと思います。
- 投稿日:2020-03-16T11:37:07+09:00
swagger-php で書く Annotation テンプレ3種
この記事は、温かみのある手作業で swagger-php の annotation を書かなければいけない人向けに、コピペで使えるannotationを提供する目的でまとめます。
単なる key value 表現のannotation
出力例
{ "id": "1", "name": "サンプル太郎", "email": "example@hoge.com", "created_at": "2006-04-13T14:12:53+09:00" }annotation
/** * @OA\Get( * tags={"Common"}, * path="/api/user", * @OA\Response( * response="200", * description="success", * @OA\JsonContent(ref="#/components/schemas/user_responder") * ), * @OA\Response( * response="204", * description="there is no authorized user", * @OA\JsonContent(ref="#/components/schemas/204_no_content") * ) * ) */tags は swagger-ui で見るときに整理されて見えるので便利のためにつけてます。
Response については別のところで定義した schema を参照するようにして、リクエストとレスポンスを別々に定義できるようにしています。以下は schema の書き方です。
まずはシンプルな方式から。/** * @OA\Schema( * schema="user_responder", * required={"id", "name", "email", "created_at"}, * @OA\Property( * property="id", * type="integer", * description="ユーザID", * example="1" * ), * @OA\Property( * property="name", * type="string", * description="ユーザの名前", * example="サンプル太郎" * ), * ~その他フィールド略。追加する場合にはカンマを忘れがちなのでお気をつけて~ * ) */クラスやフィールドに寄り添った書き方。分解して書くことができます。
/** * @OA\Schema( * schema="user_responder", * required={"id", "name"} * ) */ class UserResponder extends BaseResponder { /** * @OA\Property( * property="id", * type="integer", * description="ユーザID", * example="1" * ), */ private $id; /** * @OA\Property( * property="name", * type="string", * description="ユーザの名前", * example="サンプル太郎" * ), */ private $name;required はそれぞれのプロパティに書くのではなくて、schemaに定義します。
配列を含むannotation
出力例
{ "news": [ { "id": 5, "title": "Synergy Night Fever 2019 ──国内ベンチャーシーンを牽引する経営者3名とM&Aについて語る イベントレポート", "created_at": "2019-08-26T11:01:38+09:00" }, { "id": 4, "title": "テスト", "created_at": "2019-07-31T10:41:21+09:00" }, ] }annotation
/** * @OA\Get( * tags={"Media"}, * path="/api/news", * @OA\Response( * response="200", * description="success", * @OA\JsonContent(ref="#/components/schemas/news_list_responder") * ), * ) */呼び出される schema は以下のようになります。
/** * @OA\Schema( * schema="news_summary", * required={"id", "title", "created_at"}, * @OA\Property(property="id", type="integer", example=1), * @OA\Property(property="title", type="string", example="タイトル"), * @OA\Property(property="created_at", type="string", example="2020-01-17T11:25:28+09:00"), * ) */ /** * @OA\Schema( * schema="news_list_responder", * ) */ class NewsListResponder extends BaseResponder { /** * @OA\Property( * property="news", * type="array", * @OA\Items( * ref="#/components/schemas/news_summary" * ), * ) */ private $news;ちょっと複雑ですが、要するに、まずは
list
の schema を呼び出して、property が配列なので、さらに別のschemaを呼び出しています。
array type の property の中で schema を定義せず全て子供の property を定義することも試したのですが、それは動きませんでした。ちょっとハマりどころ。キーに対してオブジェクトを指定するannotation
出力例
{ "number_of_people_options": { "1": "~5人", "2": "5~10人" }, "headquarter_location_options": { "1": "北海道", "2": "青森県" } }annotation
/** * @OA\Get( * tags={"Common"}, * path="/api/options/info", * @OA\Response( * response="200", * description="success", * @OA\JsonContent(ref="#/components/schemas/info_options_responder") * ), * ) *//** * @OA\Schema( * schema="info_options_responder", * type="object", * required={"number_of_people_options", "headquarter_location_options"} * ) */ class InfoOptionsResponder extends BaseResponder { /** * @OA\Property( * property="number_of_people_options", * type="object", * example={1: "~5人", 2: "5~10人"} * ), */ private $numberOfPeopleOptions; /** * @OA\Property( * property="headquarter_location_options", * type="object", * example={1: "北海道", 2: "青森県"} * ), */ private $headquarterLocationOptions;schema においては object type を使用します。property の object の key value が固定であればさらに定義できますが、このケースのように固定じゃない場合には array が使えるかもしれません(この形は本運用でまだ使えていないので今後の宿題にして、かけたら更新します)。
終わりに
書き慣れるまでなかなか辛いです。慣れてしまうとパターンも少ないので案外サクサクかけます。
このannotationを使ったdocumentから実際のAPIレスポンスをテストできるのですが、それについては他の記事で書こうと思います。
- 投稿日:2020-03-16T10:45:34+09:00
【CMS】ローカル環境でJS CMSをお試しする
最近WordPress、いやだなあ~なんて思ってます。
更新通知メール多いのもなんですけど。
ブロック配置のところが分かりにくいのでメリットがまるで生かせてません。
WIXとかJIMDOとかだと重い上に細かいCSSカスタマイズが出来ないのでもだもだします。正直、静的サイトドーン! でもいいなあと思って、
改めてCMSツールを調べたところ「JS CMS」なるものを発見。・DBレス
・リアルタイムレイアウト
・完全無料
という謳い文句に惹かれていざいざお試ししてみます!
……ローカル環境で。JS CMS公式サイト
(公式にもローカル環境の手引きがあるんですけど、それとは違う方法です)本体とテンプレートをDL
JS CMSは本体とテンプレートをセットでダウンロードします。
敢えて嫌な感じに言うと、一度落としたらテンプレートは変更できません。
とは言え痒い所はHTMLとかCSSいじったりすればいいだけなのでモーマンタイ。そんなこんなで適当なところに解凍。
index.htmlがあるので、実はこれだけでもデモサイトが見れます。
全然実はじゃないけど。
でもブラウザで弄りたいので、それは後回し。環境をささっと整える
参考:PHPのダウンロードとインストール - Windows環境
JS CMSはPHPだけで動いてるので、PHPだけ入れれば自前の環境でも動かせます。
静的ジェネレーターじゃないので、あくまでちょっと動作確認したいって時だけのほうがいいと思います。
……静的ファイルは生み出す点では否定は出来ませんが。公式サイトによると「PHP4.3以上」が条件のようです。(2020/03/16現在)
なので、ver4.3以上のPHPを入れます。
①配布ページから適当なWindows向けPHPをDL(今回は7.3.15)
②Cドライブ直下にzipを解凍し、フォルダ名を「PHP」に変更
③PHPフォルダにある「php.ini-production」ファイルをコピーし、「php.ini」というファイル名で上書き保存
④エクスプローラーのPCを右クリック→プロパティ→システムの詳細設定→環境変数に移動
⑤Path→新規をクリックしてから、C:\PHP
と入力してOK
⑥コマンドプロンプトを起動し、「php -v」と入力して、以下のような画面が出たらOK
これでPHPが入りました。
文字だけの説明になってしまったので、画像で詳しく見たい方は上記の参考サイトまで。
CMSって(多分)複雑だと思うので、PHP一本で動かせるのってレアな気がします。
他のCMSになるとDB入れたりNode入れたりしそうなので、今回のは今更ながらアプリ依存な手法かと。まずローカルで試すなって話ですかね!!!
localhostを設置
参考:指定フォルダを簡単に localhost でアクセスできるようにする
さあ本題。
PHPを入れても、そのままじゃPHPファイルはブラウザでは見れません。
結論から言うと「http://」から始まらないとダメっぽいです。
なので力業……でもないですが、ローカルサーバを起動してなんとかします。①参考サイトに載っているソースをコピー
②JS CMSのフォルダ内に「local.txt」というファイルを作成し、コピーしたソースをペースト
③_local.txtを閉じてから、「local.txt」を「_local.bat」という名前にリネームこれで準備は完了です。
このバッチファイルを叩けば、現在地のフォルダがローカルサーバとして立ち上がる? ようなかんじ。
コマンド叩くよりバッチのほうがいいなあって思ったのでこんなかんじです。ちなみにでもないですが、バッチ叩くとポート番号入力画面が出ますけども、
入力せずにエンター押せばデフォルトで設定したポート番号(何もしていなければ8080)が設定されます。
ので、どのポート番号が良いのやらってなっている人はエンターだけ押せばいいと思います。
自分だ!いざいざ!
バッチを叩いてから
http://localhost:8000/_cms/
にアクセスしてみます。
こんなかんじの画面が出たら成功!
ちなみにログインIDとパスワードはデフォルトで「guest」になっています。
変更したいときは/_cms/setting/setting.php
の該当欄をいじれば良いです。あとは存分にローカルで弄り倒して下さい。
WordPressより楽しいですよ!(当社比)
- 投稿日:2020-03-16T10:39:34+09:00
変数の名前を付けるときに、絶対パスを格納していることを明記したい場合はabs_がよさげ
はじめに
相対パスではなく、絶対パスを変数に格納してほしい場合がしばしば生じます。
その際今まで私は、$setting_json_full_pathとかの名前を利用していました
abs
$abs_setting_json_pathとか、
$abs_ubuntu_isoとかの方が文字数も少なく、見た目もスッキリする上、意味もしっかり伝わるのでよいなと思った次第です。特に出典はありません。
abs
はabsolute path
、絶対パスの略称です。突き詰めると好みの問題になりそうですが、
abs
を使っていこうと思った次第でした。1
一番ベストなのは、参加したプロジェクトに合わせて使い分けることですね ↩
- 投稿日:2020-03-16T09:18:32+09:00
WSL2+docker+PHPのWindows開発環境構築(3) PHPStorm編
本ページに直接来た方はWSL2+docker+PHPのWindows開発環境構築(1) WSL2編から読んでね。
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 余談はここから ↓-------------------
関連記事:
- Bash on Ubuntu on Windowsを使う(1)
- Bash on Ubuntu on Windowsを使う(2):初期設定
- Bash on Ubuntu on Windowsを使う(3):WindowsからLinuxを使う
- WSL2+docker+PHPのWindows開発環境構築(1) WSL2編
- WSL2+docker+PHPのWindows開発環境構築(2) docker編
- WSL2+docker+PHPのWindows開発環境構築(3) PHPStorm編 ← イマココ
前回docker起動までいけた。
あとはPHPStormと繋げれば良い。('ω')ノ あとすこしやで
------------------- ↓ 本題はここから ↓-------------------
Dockerの調整
タスクバーのdockerアイコンから「setting」を選択
以下にチェックを入れて「Appli&Restart」
Expose daemon on tcp://localhost:2375 without TLS
PHPStormの調整
Pluginのインストール
兎にも角にもプラグイン。
Docker
とPHP Docker
をインストール[File]-[Setting]-[Plugins]から以下の二つをインストール
Docker
PHP Docker
(
PHP Remote Interpreter
ってのも一緒に入る)Docker Pluginの設定
「Build, Execution, Deployment」-「Docker」-「+」を押下
「TCP socker」にチェックを入れて「OK」を押下PHP Pluginの設定
「Languages & Frameworks」-「PHP」-「Cli Interpreter」-「...」を押下
「Cli Interpreters」欄の「+」を押下、
「From Docker, Vagrant, Vm, WSL, Remote...」を押下する。「Image Name」欄の「▼」を押し、
「laradock_php-fpm:latest」を選択コード補完が効いていたら成功だ。
これで実際の開発に入ることができるだろう。
(゜-゜) こんなに頑張らないと物作れないってどうなんだろ・・・。このあとGitやらXdebugやら使うことになると思うが、
それは一般的なものなので今回は省く。
(過去記事のどれかでやったっけな。)
------------------- ↓ 後書はここから ↓-------------------
これだけやって、
ようやく使えるDockerってどうなの?
(ワイだけかな)
まぁ、AWSのデプロイ考えたらdockerなのかなぁ。
ほかの方法だとイメージを量産する感じになっちゃうし。
環境を作るって観点だけで物事を考えたらいかんか。今回はlaradockでやったけど、
これがなければ環境作りだけで時間を食い潰してただろうな。
いまいちDocker Hubの扱い方がよくわからない。MySQLが起動しない
PHPとは関係ないが、
Dockerがらみ。
DockerコンテナでMySQLだけが起動しない。$ docker-compose up -d --build mysqlシーン・・・。
(?_?) アレ?
ログ見てみよう。2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started. 2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Initializing database files 2020-03-14T09:48:39.973002Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release. 2020-03-14T09:48:39.973444Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 22 2020-03-14T09:48:39.986553Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive mysqld: Cannot change permissions of the file 'ca.pem' (OS errno 1 - Operation not permitted) 2020-03-14T09:48:45.126054Z 0 [ERROR] [MY-010295] [Server] Could not set file permission for ca.pem 2020-03-14T09:48:45.126403Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it. 2020-03-14T09:48:45.126758Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-03-14T09:48:46.659592Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.|ω・) ナニコレ
データディレクトリをいったん削除してもう一回起動
2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started. 2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Initializing database files 2020-03-14T09:48:39.973002Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release. 2020-03-14T09:48:39.973444Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 22 2020-03-14T09:48:39.986553Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive mysqld: Cannot change permissions of the file 'ca.pem' (OS errno 1 - Operation not permitted) 2020-03-14T09:48:45.126054Z 0 [ERROR] [MY-010295] [Server] Could not set file permission for ca.pem 2020-03-14T09:48:45.126403Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it. 2020-03-14T09:48:45.126758Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-03-14T09:48:46.659592Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL. 2020-03-14 18:53:21+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started. 2020-03-14 18:53:21+09:00 [Note] [Entrypoint]: Initializing database files 2020-03-14T09:53:21.968144Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release. 2020-03-14T09:53:21.969067Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 22 2020-03-14T09:53:21.987587Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive 2020-03-14T09:53:27.708440Z 0 [ERROR] [MY-010295] [Server] Could not set file permission for ca.pem 2020-03-14T09:53:27.708719Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it. 2020-03-14T09:53:27.709077Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-03-14T09:53:29.169116Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.( ゚Д゚)ハァ? 余計悪化した。。。
ちょっと掘り下げてみるか。。。permissionって書いてあるから権限回りだろう・・・( ゚д゚)ハッ!
そういえばこのDocker設定作ったのはMac野郎だった。docker-compose.ymlmysql: image: mysql:8.0 ports: - 3306:3306 user: "500:500" volumes: ・・・・やっぱり。
WSL上のuserIDとdocker上のuserIDがあってない。
WSL上のUIDを確認してみよう。C:\> wsl $ id uid=1000(dozo) gid=1000(dozo) groups=1000(dozo),・・・docker-compose.ymlを調整
docker-compose.ymlmysql: image: mysql:8.0 ports: - 3306:3306 user: "1000:1000" volumes: ・・・・Mysqlのデータを全削除。
イメージを削除して、コンテナを再構成$ rm -Rf /mnt/c/Users/magic/mysql/data/* $ docker rm bc57ea450000 bc57ea450000 $ docker rmi 9b51d9270000 Untagged: mysql:8.0 Untagged: mysql@sha256:4a30434ce03d2fa39 ・・・ 79e9d07a19e3a8d49010ab9c98a2c348fa116c87 $ docker-compose up -d --build mysql Creating laradock_mysql_1 ... done直った・・・。
- 投稿日:2020-03-16T08:00:54+09:00
【個人開発】ゲージの画像を作るサービスをリリースした
個人開発のサービス まいゲージをリリースしました。
ゲージの画像を作るサービスです。
作るときに考えたこと
やっぱり、無名の人が頑張っても人気にはならないわけで、有名にするにはSNSを使う必要があります。
ツイートボタンとかを用意して、投稿されたツイートがクリックされるように、twitter cardを使いました。
もともと、ダウンロードさせて自分で画像添付にしようかと思ったけど、手間がかかって途中で諦める人が多くなるので却下。
あと、「リンクが広告臭いのがいやだ」って消される可能性もあるし、、Twitterカードの失敗
Twitterカードのメタタグをつけて、何回ツイートしても、Twitterカードがでませんでした。
理由はカードがBASE64に対応をしていなかったからです。
file_put_contents
を使って画像にしたら、無事表示されました。使用言語
JavaScript
表示部分は、JSのCanvasを使っています。
ゲージ部は、くけいで表示しています。PHP
画像を保存したりする部分です。
後々ログイン処理をすることも考えて、全ページphpにしてあります。ライブラリーなど
jQuery
これメインで使う というよりは、このあと紹介するライブラリで必要なので入ってます。
spectrum
カラーピッカーです。input colorよりも使い勝手が良さそうでした。
サービスが作りたい人へ
質より量です。たくさん作って公開しましょう。
アイデアについてですが、すでにあるもの+α でもそれっぽくなります。診断メーカー + 絵を書く でできた(と思われる)作品もありますよね。
とりあえず 作ってアップ、作ってアップ を繰り返してください。ですが、毎回別ドメインを用意してたら財布が泣くので、同じドメインのサブドメインやディレクトリにしましょう。
人気が出てきたら、ドメインをとってそれにリダイレクト。
最後に
ぜひまいゲージ使ってみてください。
#まいゲージ
— いちいち (@ichiichi_1115) March 15, 2020
まいゲージを使って、「サイトの完成度」というゲージを作ってみました。
75% / 100%
みなさんも作ってみませんか?https://t.co/e6NaPRBA2M#まいゲージ
— いちいち (@ichiichi_1115) March 15, 2020
まいゲージを使って、「アイコンの可愛さ」というゲージを作ってみました。
100点 / 100点
みなさんも作ってみませんか?https://t.co/D5lkHlRL54
あたりまえクリックするとサイトに飛びます。
最後まで読んでいただき、ありがとうございました。
- 投稿日:2020-03-16T00:50:45+09:00
Wordpress プラグインを使わずカスタムMetaBoxを作成する方法
metaboxはカスタムフィールドの強化版みたいな感じ。デフォルトのカスタムフィールドはkeyに対して値を入力するだけだが、metaboxを使うことでカレンダーや画像の選択、セレクトボックスなどのフォームを利用できるようになる。
一番簡単に実装するなら以下のようなプラグインを使う。ここではプラグインを使わず実装する方法をまとめる。
カスタムMetaBoxの作り方
metaboxを作るのに必要なのは3つの関数。1つのmetaboxで複数のフォームを作成することも可能。
- add: metaboxの定義
- save: データの保存
- html: フォームの定義
function my_custom_meta_box_add() { add_meta_box( 'post_meta_box_id', // Unique ID 'メタボックスのタイトル', // タイトル 'my_custom_meta_box_html', // フォーム関数の呼び出し 'post', // 投稿タイプ 'default' // 表示する位置 ); } function my_custom_meta_box_save($post_id) { if (array_key_exists('my_custom_meta_box_field', $_POST)) { update_post_meta( $post_id, 'my_custom_meta_box_key', $_POST['my_custom_meta_box_field'] ); } } function my_custom_meta_box_html($post) { $value = get_post_meta($post->ID, 'my_custom_meta_box_key', true); ?> <label for="my_custom_meta_box_field">メタボックスのラベル</label> <select name="my_custom_meta_box_field" id="my_custom_meta_box_field" class="postbox"> <option value="">カラーの選択</option> <option value="red" <?php selected($value, 'red'); ?>>Red</option> <option value="green" <?php selected($value, 'green'); ?>>Green</option> </select> <?php } // metaboxの定義 add_action('add_meta_boxes', 'my_custom_meta_box_add'); // metaboxのデータ保存 add_action('save_post', 'my_custom_meta_box_save');カスタムMetaBoxのフォームの表示と保存
add_meta_box()
で定義した投稿タイプに自動的に表示される。表示する位置はデフォルトでカスタムフィールドの下、
side
に設定すると、カテゴリやアイキャッチのあるサイドバーに表示される。データはfunctions.phpで
save_post
のフックを入れておくことで、記事を保存したり更新したりした際に一緒に保存されるようになる。カスタムMetaBoxのデータをテンプレートに表示
テンプレートにmetaboxのデータを表示するには、カスタムフィールドと同じ方法で良い。
get_post_meta($post->ID, 'my_custom_meta_box_key', true);記事ページでの実装例
<ul class="nav"> <li>投稿日: <?php echo get_the_date('Y-m-d'); ?></li> <li>カラー: <?php echo get_post_meta($post->ID, 'my_custom_meta_box_key', true); ?></li> </ul>