- 投稿日:2021-01-17T21:29:12+09:00
Warning: Illegal string offset ' ' in... の解決方法
今回は、SQLから取得したデータをsmartyを使って、foreachでtable表示させようとした際に発生したエラーが解決した方法をご紹介します。
発生したエラー
Warning: Illegal string offset '出力変数の各カラム名' in...下記のサイトを参考に解決したのですが、全て英語で書かれた記事なので、正直正確なエラー発生の原因がわかっていません。
どなたか詳しい原因が分かる方いましたらコメントにて教えて頂けると幸いです。
私の場合は、どうやら出力変数のキーを文字列で指定していた為に発生したようです。エラーが発生したコードと修正コード
list2.php(データ取得)修正前
<?php require_once('../db_connect2/db_connect2.php'); require( dirname( __FILE__ , 3).'/libs/Smarty.class.php' ); $smarty = new Smarty(); $smarty->template_dir = dirname( __FILE__ , 3).'/templates'; $smarty->compile_dir = dirname( __FILE__ , 3).'/templates_c'; $smarty->config_dir = dirname( __FILE__ , 3).'/configs'; $smarty->cache_dir = dirname( __FILE__ , 3).'/cache'; $smarty->escape_html = true; try { $sql = 'SELECT stock_id,purchase_date,deadline,stock_name,price,number FROM stocks WHERE 1'; $stmt = connect()->prepare($sql); $stmt->execute(); $rec = $stmt->fetch(PDO::FETCH_ASSOC); //ここで、結果セットに返された際のカラム名で添字を付けた配列を返したことが原因。 $dbh = null; } catch(Exception $e) { echo "エラー発生:" . htmlspecialchars($e->getMessage(),ENT_QUOTES, 'UTF-8') . "<br>"; print'ただいま障害により大変ご迷惑をお掛けしております。'; exit(); } $smarty->assign('stock', $rec); $smarty->display('list.tpl'); ?>修正コード
try { $sql = 'SELECT stock_id,purchase_date,deadline,stock_name,price,number FROM stocks WHERE 1'; $stmt = connect()->prepare($sql); $stmt->execute(); $rec = $stmt->fetch(PDO::FETCH_ASSOC); //ここで、結果セットに返された際のカラム名で添字を付けた配列を返したことが原因。 $dbh = null; } ↓ try { $sql = 'SELECT stock_id,purchase_date,deadline,stock_name,price,number FROM stocks WHERE 1'; $stmt = connect()->prepare($sql); $stmt->execute(); $dbh = null; }list.tpl(出力)修正前
<table class = "sorttbl" id = "myTable" border = "2"> <tr> <th class = "radio-th"></th> <th class = "purchase_date-th">購入日</th> <th class = "stock_name-th">商品</th> <th class = "price-th">値段</th> <th class = "number-th">数量</th> <th class = "deadline-th" onclick = "w3.sortHTML('#myTable','.item', 'td:nth-child(6)')">消費期限 <i class = "fa fa-sort"></i></th> </tr> //出力変数のキーを文字列で指定しているのが原因 {foreach $stock as $s} <tr class = "item"> <td><input type = "radio" name = "stockid" value = "{$s.stock_id}"></td> <td>{$s.purchase_date|date_format:'%Y-%m-%d'}</td> <td>{$s.stock_name}</td> <td>¥{$s.price}</td> <td>{$s.number}</td> <td>{$s.deadline|date_format:'%Y-%m-%d'}</td> </tr> {/foreach} </table>修正コード
{foreach $stock as $s} <tr class = "item"> <td><input type = "radio" name = "stockid" value = "{$s.stock_id}"></td> <td>{$s.purchase_date|date_format:'%Y-%m-%d'}</td> <td>{$s.stock_name}</td> <td>¥{$s.price}</td> <td>{$s.number}</td> <td>{$s.deadline|date_format:'%Y-%m-%d'}</td> </tr> {/foreach} ↓ {foreach $stock as $s} <tr class = "item"> <td><input type = "radio" name = "stockid" value = "{$s[0]}"></td> <td>{$s[1]|date_format:'%Y-%m-%d'}</td> <td>{$s[3]}</td> <td>¥{$s[4]}</td> <td>{$s[5]}</td> <td>{$s[2]|date_format:'%Y-%m-%d'}</td> </tr> {/foreach}
- 投稿日:2021-01-17T19:33:54+09:00
Dockerでapache7.4+mysql8環境構築(初期データ入り)
今更ですが、Macで表題の環境を作らなくてはいけなくなったので、構築してみました。
備忘録として書いておきます。環境
マシン macOS Catalina 10.15.7
構成
ファイル、ディレクトリの構成はざっくりと以下のようにします。
任意のディレクトリ │ ├── docker-compose.yml │ ├── html/ │ └── index.html │ ├── mysql/ │ ├── Dockerfile │ ├── data/ │ ├── init/ │ │ └── init.sql │ └── my.cnf │ ├── php-apahce/ ├── Dockerfile └── php.iniこの構築の重要な部分
docker-compose.ymlとDockerfileがこの構築の重要な部分になります。
ファイル名 説明 docker-compose.yml コンテナの構成を定義するもの。コンテナ間通信の定義もできる。 Dockerfile dockerのイメージに対する定義。 docker-compose.ymlの要素
調べて自分が認識している限りだと以下の通り
名称 意味 build Dockerfileがある位置を指定 volumus ローカル内のマウントされる場所:コンテナ内のマウントする場所 ports ポートフォワード container_name コンテナの名前 docker container lsのname environment 環境変数?変数名で何を意味するかがなんとなくわかる Dockerfileの要素
調べて自分が認識している限りだと以下の通り
名称 意味 FROM 何をどのバージョンで EXPOSE どのポートを使用するか ADD ローカルファイルをコンテナ内ファイルに追記 CMD コンテナ起動時に実行されるやつ COPY ローカルファイルをコンテナ内ディレクトリにコピーする RUN イメージ作成時に呼ばれるやつ。なのでパッケージのインストール等を書く。 構築
本編はここからです。
確認
まずコンテナの状態確認
ksk@ksknoMacBook-Pro work % docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES何もいません
./docker-compose.yml
docker-compose.ymlとは、コンテナの構成を定義するファイル
docker-compose.ymlversion: '3' services: php-apache: build: ./php-apache/ volumes: - ./html:/var/www/html ports: - 8080:80 container_name: web mysql: build: ./mysql/ volumes: - "./mysql/data:/var/lib/mysql" - "./mysql/init:/docker-entrypoint-initdb.d" environment: - MYSQL_ROOT_PASSWORD=docker - MYSQL_DATABASE=mydb - MYSQL_USER=appuser - MYSQL_PASSWORD=appuser1 container_name: db ports: - 3306:3306ymlに書いている属性?で、自分が理解していることを以下の表に書いてみる
(間違っているところを指摘してくれる優しい人いたら教えてください)./html/index.php
動作確認するために使用。
とりあえず、DBのデータを表示できれば良しとする。
volumesの定義により、htmlがドキュメントルートとなる。index.php<?php try { $db = sprintf('mysql:host=%s:3306;dbname=%s', 'mysql', 'mydb'); $dbh = new PDO($db, 'appuser', 'appuser1'); foreach($dbh->query('select * from users') as $row) { echo $row['name'] . '<br>'; } $dbh = null; } catch (PDOException $e) { echo $e; die(); } $dbh = null;hostの指定で「'mysql'」としていますが、これはdocker-compose.ymlのservice名と理解しています。
docker-compose.ymlmysql: ←これ!!! build: ./mysql/ volumes:./mysql/Dockerfile
mysql側のDockerfile
DockerfileとはDockerイメージの定義を書くファイルです。FROM mysql:8.0 EXPOSE 3306 ADD ./my.cnf /etc/mysql/conf.d/my.cnf CMD ["mysqld"]./mysql/init/init.sql
適当なテーブルとデータを詰め込むような記述にしておく
use mydb; CREATE TABLE users ( id int(10) unsigned not null auto_increment, name varchar(255) not null, primary key (id) ); insert into users(name) values('hogeo'); insert into users(name) values('fugao');./mysql/my.cnf
my.cnf[mysqld] character-set-server=utf8 default_authentication_plugin=mysql_native_password [mysql] default-character-set=utf8 [client] default-character-set=utf8default_authentication_plugin=mysql_native_passwordについて
mysqlのデフォルト認証プラグインが変わったので、デフォルトの認証プラグインを変更しています。
mysqlの環境変数でユーザ(appuser)作っていますが、mysql_native_passwordという認証プラグインで設定されます。
デフォルトのままだと、phpがmysqlへのアクセスで失敗します。./php-apache/Dockerfile
色んなサイトを見て参考にさせてもらいました。
FROM php:7.4-apache COPY ./php.ini /usr/local/etc/php/ RUN apt-get update RUN apt-get install -y zip unzip vim libpng-dev libpq-dev RUN docker-php-ext-install pdo_mysql./php-apache/php.ini
色んなサイトを見て参考にさせてもらいました。
[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"docker-compose build
上記を作った後、docker-compose.ymlと同階層で以下のコマンド実行
ksk@ksknoMacBook-Pro work % docker-compose build 〜〜〜中略〜〜〜 Successfully built e5b1c15e825e Successfully tagged work_php-apache:latest Building mysql Step 1/4 : FROM mysql:8.0 ---> d4c3cafb11d5 Step 2/4 : EXPOSE 3306 ---> Using cache ---> e11d55e213ab Step 3/4 : ADD ./my.cnf /etc/mysql/conf.d/my.cnf ---> Using cache ---> 6dd70a6b7ecd Step 4/4 : CMD ["mysqld"] ---> Using cache ---> c22190479ddf Successfully built c22190479ddf Successfully tagged work_mysql:latestコンテナ作成&起動
ksk@ksknoMacBook-Pro work % docker-compose up -d Creating web ... done Creating db ... done確認
コンテナの状態確認
ksk@ksknoMacBook-Pro work % docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b416b97d3f7b work_mysql "docker-entrypoint.s…" 2 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp db 9985abb2eb90 work_php-apache "docker-php-entrypoi…" 2 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp webコンテナが確認できました
画面確認
http://localhost:8080
こちらへアクセス以上!
- 投稿日:2021-01-17T18:21:53+09:00
【コピペ】Docker ComposeでLaravel開発環境を構築その参
前回、docker-compose.yml達と一緒にLaravelをリポジトリ管理して、かなりスッキリした。
【コピペ】Docker ComposeでLaravel開発環境を構築その弐でも、ふと思った、、、Laravelは別リポジトリで管理したいな。。。
マシンスペック
- Mac mini 2018
- macOS Catalina(10.15.x)
- Intel Core-i7 3.2GHz 6コア
- メモリ 32GB
- SSD 512GB
やること
- Docker Compose環境のLaravelを別リポジトリにする
前提条件
- 空リポジトリを用意しておく
Docker Compose環境の準備
【コピペ】Docker ComposeでLaravel開発環境を構築その弐#使い方
src/laravelを別リポジトリにする
[Mac]$ pwd /Users/xxx/docker [Mac]$ cd src [Mac]$ mv laravel laravel_bak [Mac]$ git clone <前提条件で用意したリポジトリURL> laravel [Mac]$ cp -pR laravel_bak/. laravel以降は、IDEで src/laravel を開いてプッシュする
※注)dockerをIDEで開くと、dockerの方のリポジトリにプッシュされるので、src/laravelを開くこと!
- 投稿日:2021-01-17T18:20:47+09:00
Laravelの実行環境を一から構築する
Laravelには「Homestead」と「Laradock」があり、簡単に開発環境を用意することができます。しかし、これらを本番環境で使用することはできませんし、Dockerやサーバーレスを使わない場合は一から環境を構築する必要があります。この記事では、Laravelの実行環境を一から構築する手順を説明します。
使用ソフトウェア・バージョン
- Laravel 8.21.0
- PHP 8.0(PHP-FPM)
- Nginx 1.18.0
- MySQL 8.0.22
- Ubuntu 20.04
*Dockerは使いません
参考にしたコード
HomesteadはLaravel公式の開発環境ですが、Homesteadを構築するコードがGitHubで公開されています。
「scripts/provision.sh」に環境を構築するコードが記述されています。Homesteadは多様な環境に対応できるよう多くのパッケージをインストールしているため、このコードを参考に必要なものだけインストールするようにします。
実行手順
1.PHPのインストール
2.php.iniの設定
3.PHP-FPMユーザーの作成
4.PHP-FPMの設定
5.Nginxの設定
6.Composerのインストール
7.Laravelのインストール・設定1.PHPのインストール
- ppa:ondrej/phpリポジトリをシステムに追加する
- PHP8(PHP-FPM)および拡張機能のインストール
PHPのバージョン選定
まずPHPのバージョンを選定します。利用可能なもののうち最も新しいバージョンが好ましいですが、環境によっては最新のものが利用できない場合があります。
Ubuntu20.04(LTS)の場合、apt-get installでインストールできるバージョンはPHP7.4のため、現時点(2021年1月)で最新のPHP8がインストールできません。そのため、PPAを使ってインストールするようにします。
PPA(Personal Package Archive)は個人が管理している非公式のリポジトリです。最新のパッケージが使えますがアップデートの保証はないため、リポジトリの選定と扱いには気を付ける必要があります。PHPのインストールには以下のPPAを使います。
このリポジトリは、Debianの開発者でありPHP5の頃からパッケージ管理を行っている人のもので、公式パッケージもこのリポジトリを採用していることから信頼できるリポジトリと言えます。
また、調べたところUbuntu公式のPHPパッケージのリリースは1年ほど前でしたが(更新されていない)、PPAは1ヶ月程度でアップデートされています。PPAの方がセキュリティパッチが更新される頻度が多いためより安全であると思われます。
・ppa:ondrej/phpリポジトリをシステムに追加する
sudo add-apt-repository ppa:ondrej/php sudo apt-get updateLaravelのサーバー要件
次にPHPをインストールしますが、まずは公式ホームページでLaravel 8.×のサーバー要件を確認します。
- PHP >= 7.3
- BCMath PHP Extension
- Ctype PHP Extension
- Fileinfo PHP Extension
- JSON PHP Extension
- Mbstring PHP Extension
- OpenSSL PHP Extension
- PDO PHP Extension
- Tokenizer PHP Extension
- XML PHP Extension
太字の「BCMath」「Mbstring」「XML」以外はPHPをインストールすると有効になるため、PHPおよび3つの拡張機能をインストールすれば要件を満たすことができます。
・PHP8(PHP-FPM)および拡張機能のインストール(ppa:ondrej/php)
sudo apt-get install php8.0-fpm php8.0-bcmath php8.0-mbstring php8.0-xml php8.0-mysql php8.0-zipphp-fpmとLaravelに必要な3つの拡張機能およびMySQL拡張機能をインストールしています。php8.0-zipはLaravelのインストールで必要になります。
*NginxではなくApacheを使う場合は「php8.0-fpm」ではなく「php8.0」をインストールしてください。Apacheおよび関連パッケージがインストールされます。
php8.0-fpmには以下のパッケージも含まれています。
php-common php8.0-cli php8.0-opache php8.0-readline
これらはLaravelが動作する最低限の拡張機能であるため、必要になった時点で他のパッケージもインストールしましょう。上記で紹介した「laravel/settler」のprovision.shでは、どのような拡張機能を使用しているか確認することができます。またPHP開発者の新原さんのブログも参考になると思います。
2.php.iniの設定
- FPMとCLIのphp.iniを設定する
PHPの設定ファイルは以下の2つです。
- /etc/php/8.0/fpm/php.ini(FPM)
- /etc/php/8.0/cli/php.ini(CLI)
これらのファイルは本番用の推奨設定ファイルである以下と同じものです。
- /usr/lib/php/8.0/php.ini-production(FPM)
- /usr/lib/php/8.0/php.ini-production.cli(CLI)
・FPMとCLIのphp.iniを設定する
*以下は「FPM」「CLI」両方の設定ファイルで変更 memory_limit = 512M date.timezone = "Asia/Tokyo" *以下は「FPM」の設定ファイルでのみ変更 upload_max_filesize = 100M post_max_size = 100Mなお、これらの値はHomesteadで使用されている値ですので、環境に応じて適切な値を設定してください。
また、開発環境の場合はエラーを表示するように設定します。
error_reporting = E_ALL display_errors = On3.PHP-FPMユーザーの作成
- 新規ユーザー作成
- デフォルトのパーミッション設定
- authorized_keysの設定
- デプロイディレクトリの作成
PHP-FPMをインストールするとデフォルトのユーザーである「www-data」が作成されます。このwww-dataまたはnginxユーザーを使用することもできますが、セキュリティ上好ましくないため新たにPHP-FPMユーザー(PHP実行ユーザー)を作成します。
PHP-FPMとNginxのユーザーおよびパーミッションについては以下の記事が参考になります。
NGINX and PHP-FPM. What my permissions should be?
・新規ユーザーの作成
sudo useradd phpuserこのユーザーにはsudo権限は与えません。また、第三者がファイルを操作できないよう「.bashrc」に以下を追記します。
・デフォルトのパーミッション設定
umask 0027パーミッションは以下のようになります。
- ディレクトリ 750
- ファイル 640
SSHログインまたはdeployerを使う場合は認証が必要となるため、以下に公開鍵を設定しておきます。
・authorized_keysの設定
/home/phpuser/.ssh/authorized_keys・デプロイディレクトリの作成
sudo mkdir /var/www sudo chown phpuser:phpuser /var/www sudo chmod 750 /var/wwwデプロイ先は「/var/www」でなくても構いませんが、PHP-FPMユーザーを所有者としパーミッションを750に設定しましょう。
4.PHP-FPMの設定
- PHP-FPMの設定ファイルを編集する
- PHP-FPMを再起動する
新しく作成したユーザーをPHP-FPMのユーザーとして設定します。
・PHP-FPMの設定ファイルを編集する
sudo vi /etc/php/8.0/fpm/pool.d/www.conf user = phpuser group = phpuser listen = /run/php/php8.0-fpm.sock *UNIXドメインソケット(デフォルトのまま) listen.owner = phpuser *Unixドメインソケットを使う場合に設定が必要 listen.group = phpuserUnixドメインソケットではなくTCP接続を行う場合は下記のように「IPアドレス:ポート番号」で設定します。
listen = 127.0.0.1:9000
・PHP-FPMを再起動する
sudo systemctl restart php8.0-fpm5.Nginxの設定
- NginxユーザーにPHP-FPMグループを加える
- 設定ファイルを編集 /etc/nginx/conf.d/default.conf
- Nginxの再起動
*Nginxは公式を参照してインストールしてください
・NginxユーザーにPHP-FPMグループを加える
sudo gpasswd -a nginx phpuserこれはNginxがPHP-FPMと通信を行う際にパーミッションエラーを起こさないようにするための措置です。
続いて、Laravel公式の設定例を参考にして設定ファイルを編集します。
変更する箇所は以下になります。
・設定ファイルを編集 /etc/nginx/conf.d/default.conf
server_name localhost; *本番はドメイン名 root /home/ubuntu/laravel/public *開発環境 root /var/www/current/public; *本番環境(deployerを使う場合) fastcgi_pass unix:/run/php/php8.0-fpm.sock;rootディレクティブには、Laravelの公開ディレクトリ(public)のパスを指定します。上記はdeployerを使って「/var/www/」に「laravel」というプロジェクト名でデプロイした場合のディレクトリになります。開発環境の場合はデフォルトユーザーであるubuntuのホームディレクリで良いかと思います。
・Nginxの再起動
sudo systemctl restart nginx6.Composerのインストール
Composerは公式に参照してインストールしてください。
7.Laravelのインストール・設定
- Laravelのインストール
- 「.env」の編集
- config/database.phpの編集
- config/app.phpの編集
- パーミッションの設定
ユーザーUbuntuのホームディレクリでLaravelをインストールします。
・Laravelのインストール
composer create-project --prefer-dist laravel/laravel laravel(プロジェクト名)バージョンを指定する場合は「laravel/laravel」の後に「=」を付けて指定します。
例:laravel/laravel=8.4.0
「--prefer-dist」オプションはzipでダウンロードするので高速です。
以下のコマンドでインストールされたバージョンを確認します。
cd laravel php artisan -Vインストール完了後「.env」「config/databse.php」「config/app.php」の3つの設定ファイルを編集します。
MySQLを使う場合は「.env」に以下を設定します。
・「.env」の編集
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=mysql *データベース名 DB_USERNAME=mysql-user DB_PASSWORD=mysql-password「.env」ファイルは機密情報を含みgit管理下に含まれないため、別途保存しておいてデプロイ時にコピーする必要があります。
データベースの設定ファイルは「.env」以外に「config/databse.php」があります。このファイルは「.env」に値が設定されていない場合にのみ適用されます。そのため、必要な箇所のみ変更します。
・config/database.phpの編集
'connections' => [ 'mysql' => [ 'collation' => 'utf8mb4_bin',MySQLのcollation(照合順序)である「utf8mb4_bin」は、大文字・小文字、ひらなが・カタカナ、絵文字などすべての文字を異なるものとして判定します。日本語を使う場合に適したcollationです。
続いて、app.phpでタイムゾーンを東京に変更します。
・config/app.phpの編集
'timezone' => 'Asia/Tokyo',最後に、laravelディレクリのパーミッションをディレクトリ(755)ファイル(640)にしておきます。
・パーミッションの設定
chmod -R u=rwX,g=rX,o= /home/ubuntu/laravel以上で環境の構築は完了です。開発環境であればlocalhostにアクセスするとLaravelのwelcomeページが表示されるはずです。これらの手順を毎回実行するのは煩雑なので、Ansible等を使うまたはスクリプト化して自動で行うことをお勧めします。
終わりに
LaravelにはHomesteadやLaradockなど開発環境を簡単に用意できるものがありますが、一から構築するとなるとなかなか大変です。PHPパッケージのインストールやPHP-FPM/Nginxの設定など、まとまった情報がなかったので今回まとめて記事にしました。環境構築の一助になれば幸いです。
- 投稿日:2021-01-17T18:05:58+09:00
Laravel 多対多。野球選手を例にして考えてみる
Laravel多対多について
多対多の概念や使い方が難しかったので、野球選手とポジションを例に考えてみる。
野球選手:ポジション例えば、
選手目線
大谷は投手と外野の複数のポジションを守れる
ポジション目線
外野は大谷とイチロ-が守れる
このとき、野球選手とポジションは多対多の関係にあるといえる
この考えから下記のテーブルを作成する。users(選手)目線
イチロー(1):外野(4)
大谷(2):投手(1)、外野(4)
阿部(3):捕手(2)、内野(3)ポジション目線
投手(1):大谷(2)
捕手(2):阿部(3)
内野(3):阿部(3)
外野(4):イチロー(1)と大谷(2)
このとき、選手目線からみたポジションの情報がほしいときは下記のModelを作成する
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Member extends Model { public function potisions() { // 第2,3,4引数は省略できる // 実際は第2:users_positions 第3:users_id 第4:positions_id return $this->belongsToMany('App\Potision'); } }このModelを使えば、選手目線の情報(例えば大谷は投手と外野)が取得できる。
逆にポジション目線の情報(例えば外野はイチローと大谷)が欲しい場合は下記のモデルを作成する。<?php namespace App; use Illuminate\Database\Eloquent\Model; class Potision extends Model { public function members() { // 第2,3,4引数は省略できる return $this->belongsToMany('App\User'); } }これらのModelを使って情報を取得する。
- 投稿日:2021-01-17T17:53:34+09:00
AjaxでJavaScriptからPHPのサーバに文字列を引数にしてWebAPIを実行する例
クライアント側のhtmlファイル
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <style></style> </head> <body> <input type="text" id="input_message"> <button onclick="PostString()">WebAPI実行</button> <div id="result">ここにWebAPIの結果が入ります</div> </body> </html> <script> function PostString() { const xhr = new XMLHttpRequest(); //http://XXXXXXX.jp/test.php が今回呼び出すWebAPIを記述したphpファイル xhr.open('POST', 'http://XXXXXXX.jp/test.php'); //文字列を引数にしてWebAPIを実行する(日本語も可能です) const msg = document.getElementById("input_message").value; xhr.send(msg); xhr.onreadystatechange = function() { if(xhr.readyState === 4 && xhr.status === 200) { document.getElementById( "result" ).innerHTML = xhr.responseText; }; } } </script>XMLHttpRequestオブジェクトの
sendメソッドでデータをpostして
結果があれば
responseTextプロパティで取得しますサーバー側のphpファイル
test.php<?php echo date("Y/m/d H:i:s") . "</br>"; echo "送られた文字列は" . "</br>"; echo file_get_contents("php://input") . "</br>"; echo "です" . "</br>"; ?>file_get_contents("php://input")でpostされたメタデータが取得できるようです。
- 投稿日:2021-01-17T17:53:34+09:00
JavaScriptからPHPのサーバに文字列を引数にしてWebAPIを実行する例
クライアント側のhtmlファイル
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <style></style> </head> <body> <input type="text" id="input_message"> <button onclick="PostString()">WebAPI実行</button> <div id="result">ここにWebAPIの結果が入ります</div> </body> </html> <script> function PostString() { const xhr = new XMLHttpRequest(); //http://XXXXXXX.jp/test.php が今回呼び出すWebAPIを記述したphpファイル xhr.open('POST', 'http://XXXXXXX.jp/test.php'); //文字列を引数にしてWebAPIを実行する(日本語も可能です) const msg = document.getElementById("input_message").value; xhr.send(msg); xhr.onreadystatechange = function() { if(xhr.readyState === 4 && xhr.status === 200) { document.getElementById( "result" ).innerHTML = xhr.responseText; }; } } </script>XMLHttpRequestオブジェクトの
sendメソッドでデータをpostして
結果があれば
responseTextプロパティで取得しますサーバー側のphpファイル
test.php<?php echo date("Y/m/d H:i:s") . "</br>"; echo "送られた文字列は" . "</br>"; echo file_get_contents("php://input") . "</br>"; echo "です" . "</br>"; ?>file_get_contents("php://input")でpostされたメタデータが取得できるようです。
注意事項
htmlファイルをWEB上にホスティングせず、PCのローカルディスク上でブラウザで開いて実行しても、うまく動かないようです。
- 投稿日:2021-01-17T16:32:27+09:00
【PHP】Ajax
blade.php<!-- ajax --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script> $('#answer-btn').on('click', function () { $question_id = {{ $question->id }}; $answer_choice = {{ $question->answer_choice }}; $answered_choice = Number($('input[name="answer"]:checked').val()); console.log($answered_choice); console.log($answer_choice); console.log($question_id); $.ajax({ type: "POST", url: "/question/choice", headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, data: { 'answered_choice': $answered_choice, 'question_id': $question_id }, }); }) </script> <!-- ajax -->QuestionController.php/** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function choice(Request $request) { $answered_choice = $request->answered_choice; $question_id = $request->question_id; $question = Question::find($question_id); if($answered_choice == $question->answer_choice){ $question->update(["status_num" => 2]); } else { $question->update(["status_num" => 3]); } }web.phpuse App\Http\Controllers\QuestionController; Route::resource('/question', QuestionController::class)->middleware('auth'); Route::post('/question/choice', [QuestionController::class, 'choice'])->middleware('auth');
- 投稿日:2021-01-17T16:32:27+09:00
【PHP】component
resources/js/app.js/** * First we will load all of this project's JavaScript dependencies which * includes React and other helpers. It's a great starting point while * building robust, powerful web applications using React + Laravel. */ require('./bootstrap'); /** * Next, we will create a fresh React component instance and attach it to * the page. Then, you may begin adding components to this application * or customize the JavaScript scaffolding to fit your unique needs. */ require('./components/Example'); require('./components/Answer'); //追記resources/js/componentsにanswer.jsを作成する。
- 投稿日:2021-01-17T14:33:59+09:00
素人がPHPのアップデートで失敗した話
PHPのアップデートで失敗した話
Qitaの投稿練習記事です。
ずいぶん前にサポートが切れているPHPを7.1(期限切れ)→7.4にアップデートしようと、以前から調べていたのですが、ちょっと手こずったのでメモがわりに。環境
- CentOS7
- PHP 7.1
事前にやったこと
- ユーザーさんへのメンテナンス予告
- 寝る前にスマホでggr
- 本番に備えての昼寝(平日は他業務なので)
アップデート当日
- S3にバックアップ
- remiのリポジトリに古いのがあったので、mvでリネームして無効にする
- 古いini をバックアップ
参考にしたサイト
- 自分のポカミスなのを参考サイトが悪いようにとられるとまずいので、割愛
- php centos などでググった内容を参考にしました
やっちまったこと
- php* で削除したので、phpMyAdminが動かなくなる
対処した内容
- いろいろググるもわけ分からず
- ライブラリを追加する
- サイト自体は問題無く動作しているのを確認して、落ち着くために寝る(ふて寝)
- 朝になって、いくつかライブラリ入れたら治りました
入れたライブラリ
このをインストールしてたらどれかがうまく作用して動きました
$ sudo yum install --enablerepo=remi-php74 php-fpm
$ sudo yum install --enablerepo=remi-php74 php-mbstring
$ sudo yum install --enablerepo=remi-php74 php-mysqlnd
$ sudo yum install --enablerepo=remi-php74 php-pecl-zip
$ sudo yum install --enablerepo=remi-php74 php-xml反省点
次回からは、どのライブラリがどこに作用しているのかよく調べてからにします。
- 投稿日:2021-01-17T12:48:02+09:00
【PHP】無名関数にuse()を使用する時の注意点
無名関数 (クロージャ)とは
関数名を指定せずに関数を作成できるようにするもの
公式読んで字の如く、関数名をつけずに関数を定義できます。
無名関数
pattern1$func = function() { echo 'Hello!'; }; // ←『;』をつけ忘れないように注意! $func(); // Hello!即時関数
patter2(function() { echo 'Hello!'; })(); // Hello!こちらも広義の意味で、無名関数です。PHPが()を認識したタイミングで関数が実行される仕組みとなっています
では、こちらは??
// 世界1 $word = 'Hello!!'; $func = function() { // 世界2 echo $word; }; $func(); //PHP Notice: Undefined variable: ・・・こちらはエラーになります。一見、動いても良さそうに見えますね。
これは「世界1」と「世界2」では、参照できる変数が異なるのでエラーが出ます。「世界1」から「世界2」に変数を渡すことできるのが、『use()』
use()を使ってみよう!
// 世界1 $word = 'Hello!!'; $func = function() use($word) { // 世界2 echo $word; }; $func(); // 'Hello!!'できた!
use($word)
することで、「世界2」でも「世界1」の変数$word
を参照するようになります。【本題】 use()の注意点
$word = 'Hello!!'; $func = function() use($word) { echo $word; }; $word = 'Good Morning!'; $func(); // Hello!こちらは、「Hello!」と出力されます!
use()は定義された時の変数を参照することに注意してください!これは回避する方法
$word = 'Hello!!'; $func = function() use(&$word) { // ←参照渡しにする echo $word; }; $word = 'Good Morning!'; unset($word); $func(); // Good Morning!'
$word
を参照渡しにすることで回避できます。ただ、再度$word
に値を代入されると挙動が変わってしまうので、unset()
で変数の割当を解除するようにしましょう。まとめ
無名関数を使うとスコープを小さくできるので、私はすごく好きです。
- use()に変数を3個以上書く時
- use()に参照渡しで変数を書く時
は使いたくないな〜って気持ちです。
- 投稿日:2021-01-17T12:31:17+09:00
Lravelを初めて導入した
Laravelを初めて使用して、導入に成功したのでアウトプットのために記事を投稿します。
まずは、PHPをインストールします。MacにはデフォルトでPHPが使用できるそうですが、Laravelをインストールする場合にはPHPもインストールします。
brew install php@7.4今回は、Laravel6を使用します。
Laravel6はPHP7.2以降に対応しているため7.4をインストールします。次にComposerをインストールします。
ComposerはPHPのパッケージを管理することができます。brew install composerその後、Laravelをインストール
composer global require "laravel/installer"この後、laravelのコマンドを使用できるように設定します。(php artisan serve)など
その後、laravelのプロジェクトを起動してサーバーを立ち上げます。
composer create-project laravel/laravel プロジェクト名 --prefer-dist バージョンphp artisan serveするとサーバーが立ち上がり、Laravelのトップページが表示されていれば成功です。
ちなみに「rails s]だとローカルホストのポート番号は3000でしたが、「php artisan serve」の場合は番号が8000になります。
以上、アウトプットのために投稿させていただきました。
初投稿でしたが、今後も少しずつ投稿していきたいと思いますので、宜しくお願いいたします。
- 投稿日:2021-01-17T11:55:36+09:00