20210516のPHPに関する記事は12件です。

データベースとPHPの接続、データベースの中身をPHPを使ってJSONに変える

データベースをPHPで読み込むには データベース環境は様々だと思いますが、仮想(Dockerなど)php My adminで試してできた方法をメモ程度に載せておきます。 どちらも同じ書き方でできるのでぜひコピペでパソコンの中に入れておいてください。 また、最後のほうに複数ファイルでのデータベースを一括で管理する方法も書いておきます。 <?php //データーベースホスト名 $HOST = '****.*****'; //ユーザー名 $USER = '*********'; //パスワード $PASS = '********'; //DBサーバーへ接続する $mysqli = new mysqli($HOST, $USER, $PASS); //DBを選択する //データベース名 $mysqli->select_db('*********'); //ここにSQL文を書く。なんでもかけるよ $sql = "select * from テーブル名"; $rs = $mysqli->query($sql); foreach ($rs as $value) { //これは配列を入れておくだけの箱 $temp = array(); //入れたい箱の名前=>$value['列名'] $temp = ['AAAAAA'=>$value['AAAAAA'], 'BBBBBB'=>$value['BBBBBB'], 'CCCCCC'=>$value['CCCCCC'] ]; //注意点↑ //最後は,をつけない $data[] = $temp; } //jsonにして出力 $php_json = json_encode($data, JSON_UNESCAPED_UNICODE); PHPでのアクセスするDBを共通ファイルで管理する方法 共通化するためのファイルを作ります。 ぶっちゃけ拡張子は何でもいいらしい。 //例 //dbConf.inc dbConf.inc内 dbConf.inc <?php //define (定数として扱いたい名前,定数として扱いたい文字列); //データーベースホスト名 define ('DB_URL','*******.*******'); //ユーザー名 define ('DB_USER','*******'); //パスワード define ('DB_PASS','*******'); //データベース名 define ('USE_DB','*******'); ?> ******.php内 ******.php require 'dbConf.inc'; //DBサーバーへ接続する $mysqli = new mysqli(DB_URL, DB_USER, DB_PASS); //DBを選択する $mysqli->select_db(USE_DB); ね?簡単でしょ?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPとMySQLでIPアドレスごとのスクリプト実行回数を記録する

突然Webページのアクセスが増えた!!! よく分からないリクエストが多発している!!!!! もしかしてbotでは???????? 怖い!!!!助けて!!!!!!!!!!! そんな時は訪問者のIPアドレスを取得して、スクリプト実行ごとに実行回数を記録すればよい。 特定のアドレスから異様な数のアクセスがあれば、そのアドレスはbotやスクリプトを使っているかもしれない。 saveIP.php $host = "hostname"; $db = "dbname"; $username = "username"; $pass = "password"; $dbh = new PDO("mysql:host=$host; dbname=$db; charset=utf8", $username, $pass); $ip = ip2long($_SERVER["REMOTE_ADDR"]);//IPアドレスを取得して数値に変換 $sql = "INSERT INTO table (ip, num) VALUES ($ip, 0) ON DUPLICATE KEY UPDATE SET num = num+1 WHERE ip=$ip";//IPアドレスがDBになければ挿入、既存ならnumを1増やす $req = $dbh->query($sql); DBにtableというテーブルがあり、ip(ユニーク)、numというカラムがあるという前提である。 一定時間ごとに一定以上のアクセスがあれば、リクエストされた内容を拒否すればよい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】Laravelでプロジェクトを作成する手順

Laravelでプロジェクトを作成し開発を進めていく手順をまとめておきます。 諸々のインストール手順などは割愛します。 laravelプロジェクトの作成 $ compoaser create-project laravel/laravel app このコマンドでプロジェクトの作成ができる。 $ php artisan serve このコマンドでlocalhostでサーバーが起動される。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OctoberCMS 管理画面実装テク:シンプルなリソースの権限管理を実装する

概要 先日こちらの記事でLaravel Authorization Policyを使った管理画面におけるリソースアクセス制限について書きましたが、シンプルな権限管理であればモデルのイベントフックの方がよっぽどシンプルに実装できたのでメモ。Backend.Behaviors.FormControllerを実装しているコントローラを対象とします。 やり方 モデルイベントをフック 下記の例ではProductというモデルデータがロードされたタイミング(model.afterFetchイベント)で Product::extend(function ($model) use ($user) { $model->bindEvent('model.afterFetch', function () use ($model, $user) { if (/* $modelと$userをつかって権限チェックをするロジックをここに記述 */) { // アクセス権がないときにtrueになるようにして、アクセス権なしだと例外を投げる throw new NoAccessRightToResourceException("アクセス権がありません"); } }); }); ドキュメントではモデルのイベントフック登録は基本的に Plugin::boot() に記述すると書かれているが、結局は使用される前に登録されていればよい。本記事の場合、管理画面でのみ使用したいので、管理画面のコントローラのコンストラクタに記述すれば十分間に合う。 そして、権限がなかった時の処理を例外ハンドラとして登録する。こちらも同様にコンストラクタに記述するので十分。 App::error(function (NoAccessRightToResourceException $exception) { // アクセス権がない時の処理 Flash::error($exception->getMessage()); }); 基本的にはこれだけなのだが、これだけだと例外が上記で登録した例外ハンドラまで届かない場合がある。ここが落とし穴。 \Backend\Behaviors\FormController::update を見ると catch (Exception $ex) で全ての例外がキャッチされて$this->controller->handleError($ex); でハンドルされてしまっている。つまり、このままだと上記のようにApp::errorで登録したハンドラまで例外が届かない。なので、このhandleErrorメソッドをオーバーライドしてハンドラに登録した例外の場合はthrowし直すようにする。 public function handleError($exception){ if ($exception instanceof NoAccessRightToResourceException) { // 例外を投げ直してApp::errorで登録したハンドラでハンドルさせる throw $exception; } else { parent::handleError($exception); } } 以上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelで作成したAPIをフロントエンドで受け取り画面へ描画する

前提 今回はaxiosを利用して下記URLで作成した一覧取得のapiを受け取って表示するまでを行います。 LaravelでAPIを作成 axiosとは... バックエンドとのデータのやり取りを簡単にできるライブラリです。 下記コマンドで取得するAPIのパスを確認する php artisan route:list axiosを利用してみる tsxファイルに下記を記述する。 import React, { useEffect, useState } from "react" import axios from "axios" # 型を定義する type Hoge = { id: number hoge: string fuga: boolean created_at: Date updated_at: Date } const HogePage: React.VFC = () => { const [hoges, setHoges] = useState<Hoge[]>([]) # apiを取得する const getHoges = async () => { const { data } = await axios.get<Hoge[]>('api/hoges') console.log(data) setHoges(data) } # ページにアクセスしたら実行する useEffect(() => { getHoges }) } return ( <> <div clasName="inner"> <ul className="hoge-list"> {hoges.map(hoge => ( <li key={hoge.id}> <label className="checkbox-label"> <input type="checkbox" className="checkbox-input" /> </label> <div><span>{task.title}</span</div> </li> )) } </ul> </div> <> 下記の記事のようにreactRouterのルーティングになっている前提でlocalhost:8000//hogesへアクセスすると... Laravelで作成した投稿一覧APIを取得して画面に描画することができました! Laravel環境でreactRouterのルーティングを使用できるようにする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel環境でreactRouterのルーティングを使用できるようにする

前提 reactRouterとTypeScriptで使用するための定義ファイルのライブラリをインストールする。 $ npm i -D react-router-dom @types/react-router-dom reactRouterの定義ファイルを作成する touch resources/ts/router.tsx import React from 'react' import { BrowserRouter, Switch, Route, Link } from "react-router-dom" import TaskPage from './pages/hoges' const Router = () => { return ( <BrowserRouter> <Switch> <Route path="/"> <HogePage /> </Route> </Switch> </BrowserRouter> ); } export default Router resources/ts/index.tsxへ下記を追記する import Router from "./router" ReactDom.render( <Router /> document.getElementById('app') ) 現在LaravelのRouterと競合してhomeディレクトリへ遷移してもreactRouterのRouteが反映されないのでweb.phpを下記のように編集する Route::get('{all}', function () { return view('index'); })->where(['all' => '.*']); reactRouterで遷移できるようになりました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPで1~15までの数字を繰り返し表示する

for文を使う for($i=1;$i<=15;$++){ print($i."\n"); } while文を使う $i=1; while($i<=15){ print($i); print("\n"); $i ++; } foreachを使う foreach(range(1,15) as $i){ echo $i.'<br>'; } 繰り返しの範囲が最初から決められているのならばforeachでrangeで書くのが一番簡単かも。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelで作成したAPIをテストする

前提 下記に対してPHPUnitでテストを作成していきます。 LaravelでAPIを作成する テストの設定 phpunit.xmlの設定 <server name="DB_DATABASE" value="TodoApp_testing"/> 上記のように記述されているため下記コマンドでテスト用の.envファイルを作成する cp .env .env.testing .env.testingに下記を記述する。(テスト用のデータベースを設定する) DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=HogeApp_testing DB_USERNAME=root DB_PASSWORD= テストの作成 テストディレクトリには以下の2つがあるが今回はAPIのテストなので①のテストを作成する ①Feature...一つのリクエストから始まる一連の流れをテスト ②Unit...クラスや関数の機能テスト <?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; use App\Models\Hoge; class HogeTest extends TestCase { use RefreshDatabase; // データのキャッシュを消す /** * @test * 上記のように記述することでメソッド名にtestを付けなくて良い */ public function CanGetAList() { $hoges = Hoge::factory()->count(10)->create(); $response = $this->getJson('api/hoges'); $response ->assertOk() ->assertJsonCount($hoges->count()); } /** * @test */ public function CanRegister() { $data = [ 'title' => 'テスト投稿' ]; $response = $this->postJson('api/hoges', $data); $response ->assertCreated() ->assertJsonFragment($data); } /** * @test */ public function CanBeUpdated() { $hoge = Hoge::factory()->create(); $hoge->title = '書き換え'; $response = $this->patchJson("api/hoges/{$hoge->id}", $hoge->toArray()); $response ->assertOk() ->assertJsonFragment($hoge->toArray()); } /** * @test */ public function CanBeDeleted() { $hoges = Hoge::factory()->count(10)->create(); $response = $this->deleteJson("api/hoges/1"); $response->assertOk(); $response = $this->getJson("api/hoges"); $response->assertJsonCount($hoges->count() -1); } } テストは下記のコマンドで実行する ./vendor/bin/phpunit tests/Feature/【テストファイル名】 実行するとpassしているのが分かります! (もし全体のテストを実行してpassしなかった場合は1メソッドずつに分割して試してみてください。)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelでAPIを作成する

前提 LaravelでAPIを作成していきます 今回は一覧取得/新規登録/更新/削除を実装します。 前提としてはhogeコントローラーとhogeモデル、hogeテーブルが作成されている前提です controllerで個々にインポートしなくても良くなる設定 app/Providers/RouteServiceProvider.phpへ以下のコメントアウトを解除する protected $namespace = 'App\\Http\\Controllers'; DBは下記のマイグレーションファイルで作成しておきデータも数件入れておく Schema::create('hoges', function (Blueprint $table) { $table->id(); $table->string('hoge'); $table->boolean('fuga')->default(false); $table->timestamps(); }); コントローラーの編集 app/Http/Controllers/HogeController.phpへ以下を追記する <?php namespace App\Http\Controllers; use App\Models\Task; use App\Http\Requests\HogeRequest; use Illuminate\Http\Request; class HogeController extends Controller { /** * Display a listing of the resource. * 一覧取得 * @return \Illuminate\Support\Collection */ public function index() { return Task::orderByDesc('id')->get(); } /** * Store a newly created resource in storage. * 新規登録 * @param HogeRequest $request * @return \Illuminate\Http\JsonResponse */ public function store(HogeRequest $request) { $task = Hoge::create($request->all()); return $task ? response()->json($task, 201) : response()->json([], 500); } /** * Update the specified resource in storage. * 更新 * @param \Illuminate\Http\TaskRequest $request * @param \App\Models\Hoge $hoge * @return \Illuminate\Http\JsonResponse */ public function update(HogeRequest $request, Hoge $hoge) { $hoge->title = $request->title; return $hoge->update() ? response()->json($hoge) : response()->json([], 500); } /** * Remove the specified resource from storage. * 削除 * @param \App\Models\Hoge $hoge * @return \Illuminate\Http\JsonResponse */ public function destroy(Hoge $hoge) { return $hoge->delete() ? response()->json($hoge) : response()->json([], 500); } } モデルの編集 app/Models/Hoge.phpへ以下を追記する。 # fillable内にはDBのデータを触るカラムを記述する。 protected $fillable = [ 'hoge', 'fuga', ]; ルートの編集 routes/api.phpへ以下を追記する。 Route::apiResource('hoges', 'HogeController'); 下記のURLにアクセスすると一覧取得のAPIが表示されます! localhost:8000/api/hoges
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP・Laravelで検索機能を実装(備忘録)

概要 PHP・Laravelで簡単な記事投稿アプリを作成してます。 検索機能を実装したので、備忘録として残しておきます。 ビュー index.blade.php(formタグのみ記載) <form method="GET" action="{{ route('articles.index') }}" class="d-flex"> <input class="form-control me-2" name="search" type="search" placeholder="検索" aria-label="Search"> <button class="btn btn-outline-success" type="submit">検索する</button> </form> bootstrapのナビバーに検索フォームがあるので、該当箇所をコピペしてください。 データを渡すにはname属性が必要になるので、name="search"を追記します。 また、formでキーワードを取得するので、formタグの中にmethod(データベースに保存はしないので"GET"でOK)とaction(ルートを指定)を追記します。 コントローラー ArticleController.php(indexアクションのみ記載) public function index(Request $request) { $search = $request->input('search'); $query = Article::query(); if (!empty($search)) { $query->where('title', 'LIKE', "%{$search}%") ->orWhere('body', 'LIKE', "%{$search}%"); } $articles = $query->get()->sortByDesc('created_at'); return view('articles.index', ['articles' => $articles]); } formの値を持ってくるために、Requestクラスのインスタンスをindexアクションの引数に渡しています。 $search = $request->input('search');では、index.blade.phpに書いたname="search"からデータを持ってきて、変数に代入します。 (indexアクションの一部を抜粋) $query = Article::query(); if (!empty($search)) { $query->where('title', 'LIKE', "%{$search}%") ->orWhere('body', 'LIKE', "%{$search}%"); } $articles = $query->get()->sortByDesc('created_at'); ここでクエリビルダでクエリを組み立てています。 $searchが空ではない場合は、whereメソッドを実行します。  ・第1引数・・・検索するテーブル名を指定する。  ・第2引数・・・曖昧検索をするためにオペレーターとしてLIKEを使用する。  ・第3引数・・・変数の前後に%を入れて部分一致を行う。%は曖昧検索を指示する記号のことで、0文字以上の任意の文字列を表す。 最後にgetメソッドで構成してきたクエリによるデータを取得し、作成日時が新しい順に並べています。 参考記事 Laravelで検索機能の実装 [基本] Laravel 6.x データベース:クエリビルダ 【SQL】意外と簡単!これならわかるLIKE句でのあいまい検索 【Laravel】検索機能の実装 laravelで検索機能を実装する 補足情報 PHP 7.4.1 Laravel 6.20.26
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelにReactとTypeScriptを導入する

前提 Laravelでプロジェクトを作成していて、nodeはインストール済みの想定で進めていきます。 TypeScriptをインストールする webpack.mix.js(webpackのラッパーライブラリ)を下記のように編集する mix.ts('resources/ts/index.tsx', 'public/js') .sass('resources/sass/app.scss', 'public/css'); 先ほどの編集内容を反映させる npm install プロジェクト内にnode_modulesディレクトリが作成されていればOK。 一旦下記コマンドでビルドする。 npm run prod package.jsonにwebpack.mix.jsで編集した内容の不足分が記載される(typescriptとsass) Reactをインストールする npm i -D react react-dom @types/react @types/react-dom npm install package.jsonに追記されているか確認する。 React用のTypeScriptの設定ファイルを作成する tsc --init --jsx react すると... tsconfig.jsonが作成される。 動作確認 ①webpack.mix.jsに記載した下記を作成する。 ■resources/ts/index.tsx import React from 'react' import ReactDOM from 'react-dom' const App = () => { return ( <h1>Laravel SPA</h1> ) } ReactDOM.render( <App />, document.getElementById('app') ) ■resources/sass/app.scss →resources/css/app.cssをリネームする ②下記コマンドでビルドする npm run prod ③resources/views/welcome.blade.phpをresources/views/index.blade.phpへリネームする 下記のように書き直す <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <link rel="stylesheet" href="{{ mix('/css/app.css') }}"> </head> <body> <div id="app"></div> </body> <script src="{{ mix('/js/index.js') }}"></script> </html> ④web.phpでrouteをwelcomeからindexへ変更する ⑤キャッシュ対策でファイルパスにパラメーターを付与する webpack.mix.jsに下記を追記する if (mix.inProduction()) { mix.version() } ⑥ビルトインサーバーを起動してlocalhost:8000へアクセスする php artisan serve 編集した内容が表示されていることを確認できました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CircleCIでテストを自動実行する

前提 今回は前回の記事にCircleCIを組み込んでいきます。 DockerでLEMP環境を構築する テストを作成する # Laravelプロジェクト内でテスト用の.envファイルを作成する cp .env.example .env.testing # APP_KEYを作成する php artisan key:generate --env=testing .env.testingへ下記を記載する DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel-test DB_USERNAME=root DB_PASSWORD= テストコードを作成する php artisan make:test HogeTest 下記などを参考にPHPUnitでテストを記述する https://qiita.com/tsuuuuu_san/items/46246168dc36ad2369cc https://qiita.com/nakano-shingo/items/9446568a2f9e903922d4 作成したテストをCircleCI上で実行できるように設定情報を追記する config/database.phpの'connections'に下記を追記する 'circle_testing' => [ 'driver' => 'mysql', 'host' => '127.0.0.1', 'port' => '3306', 'database' => 'circle_test', 'username' => 'root', 'password' => '', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, ], CircleCIへログインする アカウントがない場合GitHub連携で簡単に作成できます。 Projectsへ遷移するとGitHubのリポジトリが表示されるので設定したいプロジェクトのSet UP Projectボタンを押下する(開発言語など問われるので適宜選択する) CircleCIの設定ファイルを作成する 【ルートディレクトリ】へ移動して.circleci/config.ymlを作成する mkdir .circleci && touch .circleci/config.yml .circleci/config.ymlに下記のように設定を記載する version: 2 # 設定ファイルのバージョン jobs: # 実行させたいジョブの定義 build: # ジョブ名を定義する docker: # ジョブを実行するマシンを定義 # CircleCIのイメージを使用 - image: circleci/php:7.3.0-node-browsers - image: circleci/mysql:5.7 environment: - DB_CONNECTION: circle_testing working_directory: ~/CI-test steps: # マシンに対しての命令手順 - checkout # コードをレポジトリからチェックアウト - run: # コマンドを実行 name: Update apt-get command: sudo apt-get update - run: name: Docker php extensions install command: sudo docker-php-ext-install pdo_mysql - restore_cache: keys: - v1-dependencies-{{ checksum "src/composer.json" }} - v1-dependencies- - run: name: Install PHP libraries working_directory: src command: composer install -n --prefer-dist - save_cache: paths: - ./vendor key: v1-dependencies-{{ checksum "src/composer.json" }} - run: name: Run PHPUnit working_directory: src command: vendor/bin/phpunit # 定義したジョブを実行するタイミングを定義できる # 未定義だとGitプッシュがトリガーになり実行される workflows: version: 2 builid_workflow: # ワークフロー名を定義する jobs: # どのJOBを実行するか - build テストを自動で実行する GitHubにコミット/プッシュする。 CircleCIのセットアップ画面へアクセスしてStart buildingをクリックするとビルド画面へ遷移する。 すると... 無事テストが走り、テスト結果が表示されました! 次回からはGitHubにコミット/プッシュしたタイミングで自動でテストが走るようになります(.circleci/config.ymlのworkflowsでタイミングは変更できます。)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む