20200326のPHPに関する記事は7件です。

PHPでデータベースに使ってみるための備忘録

はじめに

LAMP環境を整えてPHP使っておきながらPHP内でのデータベースの使い方がわからなかったので、忘れないようにまとめておきます。

簡単なスタッフの追加ページぽい何かとスタッフ一覧ページぽいものを作りながら簡単にまとめておきます。

準備

phpMyAdminを使ってデータベースに簡単なスタッフ管理を想定したテーブルを作ります。
カラムは3つで「code,name.password」のカラムを作ります。このうちcodeを主キーにします。
データの方などは以下の画像を参照してください
Screenshot from 2020-03-26 10-00-20.png

作ってみる

スタッフ追加ページ

まずはスタッフ追加ページを作ります。
スタッフ名とパスワード・確認用パスワードを入力する欄をHTMLで用意します。

staff_add.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    スタッフ追加<br/>
    <br/>
    <form method="post" action="add_confirm.php">
        スタッフ名を入力してください<br/>
        <input type="text" name="name" style="width:200px"><br/>
        パスワードを入力してください<br/>
        <input type="password" name="pass" style="width:100px"><br/>
        パスワードをもう一度入力してください<br/>
        <input type="password" name="pass2" style="width:100px"><br/>
        <br/>
        <input type="submit" value="登録">
    </form>
</body>.
</html>

Screenshot from 2020-03-26 22-50-34.png

ここまでは大丈夫…
問題のデータベースは次から…

データベースに接続

何度もデータベース接続のコードを書くのが面倒なので、使いまわし用の関数を入れたphpファイルを作ります。

connect.php
<?php
// データベースに接続
function connectDB() {
    $dsn = 'mysql:dbname=データベース名;host=localhost;charset=utf8'; //データベース名とホスト名
    $user='root';   //データベースのユーザー名
    $password='****';    //データベースのパスワード
    try {
        $dbh = new PDO($dsn, $user,$password);
        $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        return $dbh;

    } catch (PDOException $e) {         //  データベースに接続出来なかった場合の処理
        print'エラー';      //  エラーメッセージを表示して終了
        exit();
    }
}
?>

PDOオブジェクトを使ってデータベースに接続しています。
使い方はこちら(PDOを使ったPHPでのデータベース基本操作)を参考にさせていただきました。

入力データの確認

スタッフ追加ページのstaff_add.htmlで入力されたスタッフ名とパスワードの確認ページを作ります。
スタッフ名の未入力やパスワードと確認用パスワードが一致していない場合の処理も作っていきます。

add_confirm.php
<?php


    //staff_add.htmlからデータ受取
    $staff_name=$_POST['name'];
    $staff_password=$_POST['pass'];
    $staff_password2=$_POST['pass2'];

    //エスケープ処理
    $staff_name=htmlspecialchars($staff_name,ENT_QUOTES,'UTF-8');
    $staff_password=htmlspecialchars($staff_password,ENT_QUOTES,'UTF-8');
    $staff_password2=htmlspecialchars($staff_password2,ENT_QUOTES,'UTF-8');

    //以下、入力内容確認処理

    if($staff_name==''){
        print'スタッフ名が入力されていません。<br/>';
    }else{
        print'スタッフ名:';
        print $staff_name;
        print'<br/>';
    }

    if($staff_password!=$staff_password2){
        print'パスワードが一致しません。<br/>';

    }

    if($staff_name==''||$staff_password==''||$staff_password!=$staff_password2){
        //入力内容に問題があれば戻るボタンのみ表示
        ?>
        <form>
          <input type="button" onclick="history.back()" value="戻る">
        </form>
        <?php
    }else{
        //MD5方式でパスワードをハッシュ化
        $staff_password=md5($staff_password);
        ?>
        <form method="post" action="add_done.php">
          <input type="hidden" name="name" value="<?php print $staff_name;?>">
          <input type="hidden" name="pass" value="<?php print $staff_password;?>"><br/>
          <input type="button" onclick="history.back()" value="戻る">
          <input type="submit" value="登録">
        <form>
        <?php

    }
?>

エスケープ処理については以下を参考にしました。
PHPでエスケープが必要な時と方法を最短理解!
「何故htmlspecialcharsを通すのか?」を一言でどうぞ

データベースにレコードを追加

次は、前の画面で確認したスタッフ名とハッシュ化したパスワードを受け取って、データベースに追加する処理を作ります。

add_done.php
<?php

require_once 'connect.php';
$dbh = connectDB();

try {

    $staff_name=$_POST['name'];
    $staff_password=$_POST['pass'];
    //エスケープ処理
    $staff_name=htmlspecialchars($staff_name,ENT_QUOTES,'UTF-8');
    $staff_password=htmlspecialchars($staff_password,ENT_QUOTES,'UTF-8');

    $sql='INSERT INTO テーブル名(name,password) VALUES (?,?)';   //SQL命令文 入れたいデータは「?」
    $stmt=$dbh->prepare($sql);    //準備する命令
    $data[]=$staff_name;          //「?」にセットしたいデータを順番に書き出し
    $data[]=$staff_password;
    $stmt->execute($data);        //クエリの実行

    $dbh=null;      //データベース切断

    print $staff_name;
    print 'さんを追加しました。<br/>';

}catch(Exception $e){
    print'エラー';
    exit();
}

?>
<a href="staff_list.php">戻る</a>

これでどこかミスってなければデータベースにユーザー名とパスワードのレコードが追加されてるはず。
(passwordには「test」をハッシュ化したものが入ってます)
Screenshot from 2020-03-26 23-22-07.png

スタッフ一覧

せっかくなのでデータベースに追加したスタッフの一覧を表示させるページも作ります。

staff_list.php
<?php
require_once 'connect.php';
$dbh = connectDB();

try{
    $sql='SELECT name FROM テーブル名 WHERE 1'; 
    $stmt=$dbh->prepare($sql);
    $stmt->execute();

    $dbh=null;

    print'スタッフ一覧<br/>';
    while(true){
        $rec=$stmt->fetch(PDO::FETCH_ASSOC);
        if($rec==false){
            break;
        }
        print $rec['name'];
        print '<br/>';
    }

}catch(Exception $e){
    print 'エラー';
    exit();
}

?>
<br/>
<input type="button" onclick="location.href='./staff_add.html'" value="スタッフ追加">

最後に、最初に作ったスタッフ追加ページに飛ぶ飛ぶスタッフ追加ボタンもつけておきます。

Screenshot from 2020-03-26 23-28-00.png
出来た出来た。追加と表示しかしてないけどとりあえず出来た。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【wordpress】【css】【PHP】cssが更新されないor読み込まれない

メモです

CSSの読み込みはどこに書く?WordPress公式マニュアルに書かれている正しい手順。

以下、追加

functions.php

function add_css_js() {//関数名add_css_js()を作成
    //CSSの読み込みはここから

    //全てのページにstyle.cssを読み込み
  wp_enqueue_style('style',get_template_directory_uri().'/style.css','',date('YmdGi', filemtime( get_template_directory().'/style.css' )),'' );

    //全てのページにcss/store.cssを読み込み
    wp_enqueue_style('store', get_template_directory_uri().'/css/store.css');

    //固定ページスラッグcontact か 投稿ID46の記事 か カスタム投稿タイプadd_newsの記事 か カスタム投稿タイプadd_newsの一覧だった場合、css/store2.cssを読み込み
    if (is_page('contact')||is_single(46) || is_singular('add_news') || is_post_type_archive('add_news')) {
        wp_enqueue_style('store2', get_template_directory_uri().'/css/store2.css');
    }

    //JavaScriptの読み込みはここから

    //全てのページにjs/pagetop.jsを読み込み
    wp_enqueue_script('pagetop', get_template_directory_uri().'/js/pagetop.js');

    //トップページのみ
    if (is_home()) {

    //js/main.jsをfooter直下で読み込み  
        wp_enqueue_script('main', get_template_directory_uri().'/js/main.js', array( 'jquery' ), '', true); 
    }
}
//関数名add_scripts()を表側で呼び出す
add_action('wp_enqueue_scripts', 'add_css_js);

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Paginate

ページネーションメソッドを使ってページャの実装

HogeController.php
    use App\Models\Hoge; #Hogeモデルがある前提

    $hoges = Hoge::paginate(5);
    return view('hoge.index', ['hoges' => $hoges]);
style.scss
  .page ul li{
    display: inline;
  }
hoge/index.blade.php
  @foreach($hoges as $hoge)
    <tr>
      <td>{{ $hoge->id }}</td>
      <td>{{ $hoge->name }}</td>
      <td>{{ $hoge->email }}</td>
      <td>{{ $hoge->age }}</td>
    </tr>
  @endforeach

<div class="page">
    {{ $hoges->links() }}
</div>

1.コントローラでpaginateメソッドを使って表示件数を指定
2.viewでlinksメソッドでページャを表示

orderByを使ってソート

#上記の例にorderByメソッドを追加するだけ
Hoge::orderBy('age', 'desc')->paginate(5);

参考URL

https://blog.hiroyuki90.com/articles/laravel-pagination/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelでTDDを始めよう

LaravelでのUnitTestを始めよう

TestUnitを始める上で勢いで始めないように設計しましょう。

・基本的に読むべきこと
https://phpunit.readthedocs.io/ja/latest/
https://readouble.com/laravel/5.5/ja/testing.html

アンチパターンとベストプラクティス
https://www.ryuzee.com/contents/blog/3982

  1. テストの中で何もテストしていない
    書きかけの場合は、テストに未完成の印をつけるなどしましょう
    https://phpunit.readthedocs.io/ja/latest/incomplete-and-skipped-tests.html

  2. 1つのテストメソッドの中で色々テストし過ぎている

  3. 引数に真にしたい条件を与えてなんでもassertTrueでチェックしている
    @dependsアノテーションを使ってテストの実行順序を制御しつつ分割を行うべきです。

  4. テストデータのパターンが複数あるのを理由に1つのテストの中で順番に検証する
    引数は検証対象の値やオブジェクトであるべきで、テストの意図を伝わりやすくすべきです。

  5. テストが分類されていない。適切なフォルダ構成になっていない
    解決策は適切にフォルダに分けて配置したり、テストスイートをつくったり、@groupアノテーションを使ってテストを分類します。

LaravelでPhpUnitを使う
LaravelでPHPUnitを使用する際、デフォルトの状態であればtests/TestCase.phpが作成されており、全てのテストクラスはこれを継承してテストを行います。

参考:https://memorandumrail.com/laravel-phpunit/
LaravelではデフォルでhFeatureとUnitというディレクトリに分かれていて、Feature には機能テスト、Unit にはユニットテストを書く構成になっています。
関数単位、クラス単位の場合はUnit

Mockeryを使うと疑似モックを作ってくれるので便利らしい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Mac Laravelのライブラリ「laravel-dompdf」を日本語表示に対応させる

目的

  • Laravelにライブラリ「laravel-dompdf」を入れたが、日本語化されない問題があったため改善する

実施環境

  • ハードウェア環境
項目 情報 備考
OS macOS Catalina(10.15.3)
ハードウェア MacBook Air (11-inch ,2012)
プロセッサ 1.7 GHz デュアルコアIntel Core i5
メモリ 8 GB 1600 MHz DDR3
グラフィックス Intel HD Graphics 4000 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3
Laravel バージョン 7.0.8
  • ライブラリ環境
項目 情報 備考
laravel-dompdf v0.8.6 アプリ名ディレクトリに移動後コマンド`composer show -i

実施条件

実施方法概要

  • Bladeファイルを利用した日本語化対応の方法をまとめる。
  1. 準備
  2. フォントのファイルの取得
  3. ライブラリに登録するためのスクリプト取得
  4. ライブラリに登録
  5. 確認

実施方法詳細

  1. 準備

    1. 下記コマンドを実行してフォントのファイルを設置するディレクトリを作成する

      $ mkdir アプリ名ディレクトリ/fonts
      
  2. フォントのファイルの取得

    1. 下記リンク先にアクセスする。

      IPAフォント ダウンロードページ

    2. リンク先の「TTFファイル」の「4書体パック」のzipをクリックしてフォントをインストールする。

      laravel_dompdf_japanese_md_と_IPAフォントのダウンロード.png

    3. お使いのMacのダウンロードフォルダにダウンロードされたフォントのzipファイル「IPAfontXXXXX.zip」を解凍する。(Xには任意の数字)

    4. 下記コマンドを実行して、解凍した「IPAfontXXXXX」の中のファイル郡を先に作成したアプリ名ディレクトリ/fontsにコピーする。

      $ cd アプリ名ディレクトリ
      $ cp ~/Downloads/IPAfont00303/* fonts/
      
    5. フォントのファイルを設置したアプリ名ディレクトリ/fonts直下の状態を下記に記載する。

      • ~アプリ名ルートフォルダ/fonts
        • IPA_Font_License_Agreement_vX.X.txt
        • Readme_IPAfontXXXXX.txt
        • ipag.ttf
        • ipagp.ttf
        • ipam.ttf
        • ipamp.ttf
  3. ライブラリに登録するためのスクリプト取得

    1. 下記のリンク先にアクセスする。
    2. 「Clone or download」をクリックする。

      dompdf_utils__Utility_scripts_for_use_with_the_dompdf_library.png

    3. 「Download ZIP」をクリックする。

      dompdf_utils__Utility_scripts_for_use_with_the_dompdf_library_と_laravel_dompdf_japanese_md.png

    4. お使いのMacのダウンロードフォルダにダウンロードされたzipファイル「utils-master.zip」を解凍する。

    5. 下記コマンドを実行して解凍したフォルダ「utils-master」の中の「load_font.php」をアプリ名ディレクトリ直下にコピーする。

      $ cd アプリ名ディレクトリ
      $ cp ~/Downloads/utils-master/load_font.php .
      
    6. アプリ名ディレクトリ直下に「load_font.php」があることを確認する。

  4. ライブラリに登録

    1. 下記コマンドを実行する。(筆者環境での下記コマンドの実行後の出力を付録に記載する。)

      $ php load_font.php ipag fonts/ipag.ttf
      
    2. 下記コマンドをアプリ名ディレクトリで実行してフォントの設定ファイルを確認する。

      $ cd アプリ名ディレクトリ
      $ vi vendor/dompdf/dompdf/lib/fonts/dompdf_font_family_cache.php
      
    3. 先のコマンドを実行して開いたファイルに下記の記載がある事を確認する。

      vendor/dompdf/dompdf/lib/fonts/dompdf_font_family_cache.php
      'ipag' => array(
      'normal' => $fontDir . '/ipag',
      'bold' => $fontDir . '/ipag',
      'italic' => $fontDir . '/ipag',
      'bold_italic' => $fontDir . '/ipag',
      ),
      
    4. 下記コマンドを実行してスクリプトファイルにより作成されたライブラリが読むためのフォントデータをコピーする。

      $ cd アプリ名ディレクトリ
      $ cp -r vendor/dompdf/dompdf/lib/fonts storage/
      
  5. 確認

    1. 下記コマンドを実行してアプリ名ディレクトリ/resource/viewに「test」フォルダを作成する。

      $ cd アプリ名ディレクトリ
      $ mkdir resources/views/test
      
    2. 下記コマンドを実行してTestコントローラを作成する。

      $ cd アプリ名ディレクトリ
      $ php artisan make:controller TestController
      >Controller created successfully.
      
    3. 下記コマンドを実行して先に作成したコントローラを開く。

      $ cd アプリ名ディレクトリ
      $ vi app/Http/Controllers/TestController.php
      
    4. 先のコマンドで開いたコントローラをの内容を下記の様に修正する。

      アプリ名ディレクトリ/app/Http/Controllers/TestController.php
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      
      use PDF;
      
      class TestController extends Controller
      {
          public function japanese_pdf_test() {
              $pdf = PDF::loadView('test.japanese_pdf_test');
              return $pdf->stream();
          }
      }
      
    5. 下記の記載をアプリ名ディレクトリ/routesにあるweb.phpのルーティングファイルに追記する。

      アプリ名ディレクトリ/routes/web.php
      Route::get('/japanese_pdf_test', 'TestController@japanese_pdf_test');
      
    6. 下記コマンドを実行してビューファイルを作成し開く。

      $ cd アプリ名ディレクトリ
      $ vi resources/views/test/japanese_pdf_test.blade.php
      
    7. 開いたビューファイルに下記の内容を記載する。

      アプリ名ディレクトリ/resources/views/test/japanese_pdf_test.blade.php
      <!doctype html>
      <html>
        <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
          <title>PDF</title>
          <style>
          body {
          font-family: ipag;
          }
          </style>
        </head>
        <body>
            <h1>こんにちは</h1>
        </div>
        </body>
      </html>
      
    8. 下記コマンドを実行してローカルサーバを起動する。

      $ cd アプリ名ディレクトリ
      $ php artisan serve
      
    9. 下記のリンク先にアクセスしブラウザから文字化けせずに「こんにちは」とPDFとして出力されることを確認する。

付録

  • コマンドphp load_font.php ipag storage/fonts/ipag.ttfを実行した際の筆者の環境でのターミナル出力を下記に記載する。

    $ php load_font.php ipag fonts/ipag.ttf
    >Unable to find bold face file.
    >Unable to find italic face file.
    >Unable to find bold_italic face file.
    >Copying fonts/ipag.ttf to /Users/shun/workspace/study/laravel/calculation_drill_app/vendor/dompdf/dompdf/lib/fonts/ipag.ttf...
    >Generating Adobe Font Metrics for /Users/shun/workspace/study/laravel/calculation_drill_app/vendor/dompdf/dompdf/lib/fonts/ipag...
    >PHP Notice:  Trying to access array offset on value of type null in /Users/shun/workspace/study/laravel/calculation_drill_app/vendor/phenx/php-font-lib/src/FontLib/AdobeFontMetrics.php on line 142
    >PHP Stack trace:
    >PHP   1. {main}() /Users/shun/workspace/study/laravel/calculation_drill_app/load_font.php:0
    >PHP   2. install_font_family() /Users/shun/workspace/study/laravel/calculation_drill_app/load_font.php:201
    >PHP   3. FontLib\TrueType\File->saveAdobeFontMetrics() /Users/shun/workspace/study/laravel/calculation_drill_app/load_font.php:155
    >PHP   4. FontLib\AdobeFontMetrics->write() /Users/shun/workspace/study/laravel/calculation_drill_app/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php:361
    >
    >Notice: Trying to access array offset on value of type null in /Users/shun/workspace/study/laravel/calculation_drill_app/vendor/phenx/php-font-lib/src/FontLib/AdobeFontMetrics.php on line 142
    >
    >Call Stack:
    >    0.0086     423096   1. {main}() /Users/shun/workspace/study/laravel/calculation_drill_app/load_font.php:0
    >    0.0484    4914016   2. install_font_family() /Users/shun/workspace/study/laravel/calculation_drill_app/load_font.php:201
    >    0.0858    5068992   3. FontLib\TrueType\File->saveAdobeFontMetrics() /Users/shun/workspace/study/laravel/calculation_drill_app/load_font.php:155
    >    0.0862    5103120   4. FontLib\AdobeFontMetrics->write() /Users/shun/workspace/study/laravel/calculation_drill_app/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php:361
    

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC-CUBE4 プラグインの作り方 ~ セットアップからインストールまで

EC-CUBE4向けプラグインの作り方

プラグインは、composer.jsonだけあれば作れる。

まずはMyPluginというフォルダを作って、その中にcomposer.jsonファイルを入れる。

必要な設定項目は、name、version、desctription、codeのみ。他は固定。

app/Plugin/MyPlugin/composer.json

{
  "name":"ec-cube/MyPlugin",
  "version":"1.0.0",
  "description":"my plugin",
  "type":"eccube-plugin",
  "require": {
    "ec-cube/plugin-installer": "~0.0.6"
  },
  "extra":{
    "code":"MyPlugin"
  }
}

作成したプラグインをインストールする

プラグインをインストールするにはコマンドラインを使うか、いったん圧縮して管理画面からインストールする。

// コマンドラインからインストール
bin/console eccube:plugin:install --code=MyPlugin

// いったん圧縮
cd app/Plugin/MyPlugin
tar --exclude  ".git" --exclude ".DS_Store" -cvzf ../MyPlugin.tar.gz *

インストール後はこんな感じ。

plugin1.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

少し奇妙なPHPの不等号

ひょんな拍子に、PHPの不等号に関する恐ろしい事実を発見してしまいました。

まずは穴埋め

$a = ();
$b = ();

if($a < $b && $b < $a) {
  echo 'まさかこんなところには来ないよね';
}

実は、$a < $b && $b < $aという式を成立させてしまう方法が存在します。

配列の比較

ふつうの変数であれば比較基準は1通りなので、$a < $b && $b < $aなんていう事態に陥ることはないのですが、そうは問屋が卸さないのがPHPです。PHP標準で、配列にも比較基準を用意しています(PHPマニュアル)。

  • 配列の要素数が異なる場合、要素数が少ないほうが小さい
  • 要素数が同じ場合、キーを順に比較していって中身の大小で比較する(同じキーがなければ判定不能)

そして、PHPの連想配列はキーの順序が保存される、ということで、「同じキーがあるけど順番の違う」配列を用意して比較を行えば、パラレルワールドに突入です。

実際にやってみた

$a = ['foo' => 2, 'bar' => 5];
$b = ['bar' => 4, 'foo' => 3];

if($a < $b && $b < $a) {
  echo 'まさかこんなところには来ないよね';
}

3v4lでの実行結果

この場合、$a < $bではfooのキーが、$b < $aではbarのキーが先に比較されます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む