ntorelabo
【React】Todoアプリ

todoアプリ作成

参考サイト:
https://www.youtube.com/watch?v=nRCNL9T3J98

ノードjsインストール確認、Reactひな型作成

PS C:\Users\…\react-project> node -v
v18.17.1
PS C:\Users\…\react-project> npx create-react-app react-tutorial  

→完了するとHappy hacking!の表示

不要なファイルの削除\src\App.test.js src\logo.svg \src\reportWebVitals.js \src\setupTests.js

コンポーネントの作成

▼\src\TodoList.jsを作成

VSCodeプラグインES7+ React/Redux/React-Native をインストールしていればrafceタブ補完と入力すれば下記のように関数コンポーネントが入力されます

import React from 'react'
export const TodoList = () => {
  return (
    <div>TodoList</div>
  )
}

▼App.jsを編集

インポートの記載

import { TodoList } from "./TodoList";
function App() {
  return (
    <div className="App">
      <TodoList />
    </div>
  );
}
export default App;

入力欄、ボタン作成

▼.js

import TodoList from "./TodoList";

function App() {
  return (
    <div className="App">
      <div>
        <TodoList />
        <input type="text" />
        <button>タスクを追加</button>
        <button>完了したタスクの削除</button>
        <div>残りのタスク:0</div>
      </div>
    </div>
  );
}

export default App;

1)useStateで状態を監視→変更で再レンダリング
2)propsでtodos={todos}でコンポーネント間のデータの受け渡し

▼App.js

import { useState } from "react";
import TodoList from "./TodoList";

function App() {
  const [todos, setTodos] = useState(["Todo1", "Todo2"]);

  return (
    <div className="App">
      <div>
        <TodoList todos={todos}/>
        <input type="text" />
        <button>タスクを追加</button>
        <button>完了したタスクの削除</button>
        <div>残りのタスク:0</div>
      </div>
    </div>
  );
}

export default App;

useState()

useState()は、関数コンポーネントでstateを管理(stateの保持と更新)

stateとはコンポーネントが内部で保持する「状態」

▼TodoList.js

import React from 'react'

const TodoList = ({ todos }) => {
  return (
    <div>{todos}</div>
  )
}

export default TodoList

Todo.jsを作成(各タスクをコンポーネントにおきかえる)

▼TodoList.js

import React from 'react';
import Todo from './Todo';

const TodoList = ({ todos }) => {
  return todos.map((todo) => <Todo todo={todo} />);
}

export default TodoList

▼Todo.js

import React from 'react'

const Todo = ({ todo }) => {
  return (
    <div>{todo}</div>
  )
}

export default Todo

todoをオブジェクトとして管理

▼App.js

function App() {
  const [todos, setTodos] = useState([
    { id: 1, name: "Todo1", completed: false },
  ]);

▼Todo.js

const Todo = ({ todo }) => {
  return (
    <div>{todo.name}</div>
  )
}

チェックボックスの実装(チェックオンオフは後から実装)

▼Todo.js

    <div>
        <label>
            <input type="checkbox" checked={todo.completed} readOnly />
        </label>
        {todo.name}
    </div>

タスクの追加 
useRefで要素の取得(オブジェクトにおけるスプレッド構文の追加)

▼useRefで取得した内容をconsole.log()で確認

▼App.js

import { useState, useRef } from "react";
import TodoList from "./TodoList";

function App() {
  const [todos, setTodos] = useState([
    { id: 1, name: "Todo1", completed: false },
  ]);

  // useRefでinputの値を取得
  const todoNameRef = useRef();

  // タスクを追加する
  const handleAddTodo = () => {

    const name = todoNameRef.current.value;

    // 空白のタスクを生成しない
    if(name === "") return;

    // setTodosでTodosの内容を更新
    // オブジェクトにおけるスプレッド構文の追加
    setTodos((prevTodos) => {
      return [...prevTodos, { id: "1", name: name, completed: false }];
    });

    todoNameRef.current.value = null;
  };

  return (
    <div className="App">
      <div>
        <TodoList todos={todos}/>
        <input type="text" ref={todoNameRef} />
        <button onClick={handleAddTodo}>タスクを追加</button>
        <button>完了したタスクの削除</button>
        <div>残りのタスク:0</div>
      </div>
    </div>
  );
}

export default App;

対応)Warning: Each child in a list should have a unique “key” prop.

uuidインストール

ユニークキーの生成が可能

https://www.npmjs.com/package/uuid

npm install uuid→package.jsonにてインストールの確認ができます

  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "uuid": "^9.0.1",
    "web-vitals": "^2.1.4"
  },

▼App.jsを編集

import { useState, useRef } from "react";
import { TodoList } from "./TodoList";
import { v4 as uuidv4 } from 'uuid';

function App() {
  const [todos, setTodos] = useState([
    { id: 1, name: "Todo1", competed: false }
  ]);

  const todoNameRef = useRef();

  const handleAddTodo = () => {
    // タスクを追加
    const name = todoNameRef.current.value;
    setTodos((prevTodos) => {
      return [...prevTodos, { id: uuidv4(), name: name, completed: false }]
    });
    todoNameRef.current.value = null;
  };

▼TodoList.jsを編集

export const TodoList = ({ todos }) => {
  return todos.map((todo) => <Todo todo={todo} key={todo.id}/>);
}

初期値をから行列にApp.js

function App() {
  const [todos, setTodos] = useState([]);

toggleTodoでチェックボックスを管理

▼App.jsを編集


  // チェックボックスの操作
  const toggleTodo = (id) => {

    // 直接値を変更しない為newTodosにコピーしている
    const newTodos = [...todos];

    // 引数のidとtodoのidが一致したら、completedを反転
    const todo = newTodos.find((todo) => todo.id === id);
    todo.completed = !todo.completed;
    setTodos(newTodos);
  };

  return (
    <div className="App">
      <div>
        <TodoList todos={todos} toggleTodo={toggleTodo} />
        <input type="text" ref={todoNameRef} />
        <button onClick={handleAddTodo}>タスクを追加</button>
        <button>完了したタスクの削除</button>
        <div>残りのタスク:0</div>
      </div>
    </div>
  );
}

export default App;

▼TodoList.jsを編集


const TodoList = ({ todos, toggleTodo }) => {
  return todos.map((todo) => <Todo todo={todo} key={todo.id} toggleTodo={toggleTodo} />);
}

▼Todo.jsを編集

import React from 'react'

const Todo = ({ todo, toggleTodo }) => {

    const handleTodoClick = () => {
        toggleTodo(todo.id);
    };

    return (
        <div>
            <label>
                <input 
                    type="checkbox" 
                    checked={todo.completed} 
                    readOnly 
                    onClick={handleTodoClick} 
                />
            </label>
            {todo.name}
        </div>
    )
}

export default Todo

残りのタスクの数をいれる

▼App.jsを編集


    <div className="App">
      <div>
        <TodoList todos={todos} toggleTodo={toggleTodo} />
        <input type="text" ref={todoNameRef} />
        <button onClick={handleAddTodo}>タスクを追加</button>
        <button>完了したタスクの削除</button>
        <div>残りのタスク:{todos.filter((todo) => !todo.completed).length}</div>
      </div>
    </div>

完了したタスクの削除

  // 完了したタスクの削除
  const handleClear = () => {
    const newTodos = todos.filter((todo) => !todo.completed);
    setTodos(newTodos);
  }

  return (
    <div className="App">
      <div>
        <TodoList todos={todos} toggleTodo={toggleTodo} />
        <input type="text" ref={todoNameRef} />
        <button onClick={handleAddTodo}>タスクを追加</button>
        <div>残りのタスク:{todos.filter((todo) => !todo.completed).length}</div>
        <button onClick={handleClear}>完了したタスクの削除</button>
      </div>
    </div>
  );
}

レンタルサーバで公開

参考サイト:https://zenn.dev/kiriyama/articles/538face511307d

▼package.jsonを編集

▼\public.htaccessを作成(publickフォルダに「.htaccess」のファイルを作成)

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

▼プロジェクトディレクトリで下記のコマンドでビルド

npm run build

buildというフォルダが作成されるので、その中身をFTPでアップロード

アップロードしたサイト:https://internet.mints.ne.jp/react-todo/


https://www.youtube.com/watch?list=PLX8Rsrpnn3IWPoM7-1YPDksRRkamRY25k&time_continue=8&v=XKSYF2aZnkQ&embeds_referring_euri=https%3A%2F%2Fsbucks-blog.com%2F&source_ve_path=Mjg2NjY&feature=emb_logo

Laravelの開発環境をDockerで構築し、さくらインターネットにデプロイする方法

大まかなフロー

  1. ローカルでDockerで作成した環境にLaravelをインストール
  2. srcフォルダをGithubにリポジトリを作成

ローカル環境

laravel-project/
│
├── docker/
│   ├── php/
│   │   └── Dockerfile
│   └── nginx/
│       └── default.conf
│
├── docker-compose.yml
└── src/     # まだ空

phpの設定

docker\php\Dockerfile

FROM php:8.2-fpm

# 必要なパッケージを全て最初からインストール
RUN apt-get update && apt-get install -y \
    git \
    zip \
    unzip \
    nodejs \
    npm \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    sqlite3

# PHPの拡張機能をインストール
RUN docker-php-ext-install pdo_mysql

# Composerインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

nginxの設定

docker\nginx\default.conf

server {
    listen 80;
    root /var/www/html/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Dockerの設定

docker-compose.yml

version: '3'
services:
  app:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    volumes:
      - ./src:/var/www/html

  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret
# Dockerコンテナを起動
docker-compose up -d

Laravelのインストール

# 1. まず、appコンテナに入る場合
docker-compose exec app bash

# 2. コンテナ内で実行されるComposerコマンド
composer create-project laravel/laravel .

composer create-project

  • Composerの機能で新しいプロジェクトを作成する命令
  • PHP のパッケージマネージャーである Composer の機能
src/
├── app/          # アプリケーションのコアコード
├── bootstrap/    # フレームワークの起動ファイル
├── config/       # 設定ファイル
├── database/     # データベース関連ファイル
├── public/       # Webサーバーのドキュメントルート
├── resources/    # ビュー、CSS、JSなど
├── routes/       # ルーティング定義
├── storage/      # ログ、キャッシュなど
├── tests/        # テストファイル
├── vendor/       # Composer依存パッケージ
├── .env          # 環境設定ファイル
├── artisan       # コマンドラインツール
└── composer.json # パッケージ依存関係の定義

.envファイル編集

src/.env

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:q2QBqULWSbDokQMj1CEWuMZlhr3Y8SXtF5AiAUQUAEk=
APP_DEBUG=true
APP_URL=http://localhost:8080  # ポート番号を追加

LOG_CHANNEL=stack
LOG_LEVEL=debug

DB_CONNECTION=sqlite
# DB_DATABASE=/var/www/html/database/database.sqlite  # コメントアウトして自動設定を使用

SESSION_DRIVER=file  # データベースではなくfileを使用
SESSION_LIFETIME=120

CACHE_DRIVER=file    # データベースではなくfileを使用
QUEUE_CONNECTION=sync  # データベースではなくsyncを使用

権限設定

# storage(ログ、キャッシュ用)
docker-compose exec app chown -R www-data:www-data storage
docker-compose exec app chmod -R 775 storage

# bootstrap/cache(フレームワークキャッシュ用)
docker-compose exec app chown -R www-data:www-data bootstrap/cache
docker-compose exec app chmod -R 775 bootstrap/cache

# database(SQLite用)
docker-compose exec app chown -R www-data:www-data database
docker-compose exec app chmod -R 775 database

SQLiteデータベース設定

docker-compose exec app touch database/database.sqlite
docker-compose exec app chmod 664 database/database.sqlite
docker-compose exec app chown www-data:www-data database/database.sqlite

キャッシュクリア

  • .envファイルの変更を反映するため
  • 設定の変更(DB接続情報など)を確実に適用するため
docker-compose exec app php artisan config:clear
docker-compose exec app php artisan cache:clear

マイグレーション実行

データベースのテーブルを作成

# データベースのテーブルを作成
docker-compose exec app php artisan migrate

npmのインストールと初期設定

# コンテナ内でnpm installを実行
docker-compose exec app npm install

# 開発用のビルドを実行
docker-compose exec app npm run dev

デプロイ方法

方法 1)本番環境でComposerインストールする(一般的)

vendorディレクトリの中身のライブラリがサイズが大きいので、package.json?だけ共有して、それぞれの環境でインストールするのが一般的(重たいファイルのやり取りはしたくない)

  • ✅ リポジトリが軽量
  • ✅ 各環境で最適化されたインストール
  • ❌ インストール時間が必要
  • ❌ インストール失敗のリスク
  • ❌ サーバーにComposerが必要

方法 2)vendor/ディレクトリを含めてバージョン管理して本番環境にアップロードする
→ 今回はこちらの手順を実施

  • ✅ デプロイが確実
  • ✅ Composerインストール不要
  • ❌ リポジトリが大きくなる

Gitリポジトリ設定

src/                  # Laravelプロジェクト
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/          # ★これを含める(Composerインストール不要に)
├── composer.json
├── composer.lock
└── .gitignore           # Docker関連ファイルは除外

本番環境での設定

.envファイルの作成と設定

.env.exampleをコピー

# .env ファイルを作成
cp .env.example .env

.env

APP_NAME=Laravel
APP_ENV=production
APP_DEBUG=false
APP_URL=https://siennahare23.sakura.ne.jp/laravel-d01

DB_CONNECTION=sqlite
# その他のDB設定はコメントアウト

SESSION_DRIVER=file
CACHE_DRIVER=file

権限の設定

# 権限を設定
chmod -R 775 storage bootstrap/cache

ストレージリンクの作成

アップロードされたファイル(画像など)を公開アクセス可能にする storage/app/publicpublic/storage をリンクさせる

# ストレージリンクの作成
php artisan storage:link
laravel-dir/
├── public/          # Webからアクセス可能なディレクトリ
│   └── storage -> ../storage/app/public  # シンボリックリンク
│
└── storage/
    └── app/
        └── public/  # 実際のファイル保存場所

ユーザーが画像をアップロードする→画像は storage/app/public に保存される →public/storage からアクセス可能になる

キャッシュのクリアと再生成

php artisan config:clear  # 設定ファイルのキャッシュを削除
php artisan cache:clear   # アプリケーションのキャッシュを削除
php artisan view:clear    # コンパイル済みビューファイルを削除

php artisan config:cache  # 設定ファイルを1つのファイルにまとめる
php artisan route:cache   # ルート情報をキャッシュ
php artisan view:cache    # ビューファイルをプリコンパイル

.htaccessの設定

laravel-dir/.htaccess

# PHPファイルの実行設定(.phpの拡張子のファイルをPHPスクリプトとして実行)
AddHandler application/x-httpd-php .php

# サーバー基本設定
# +SymLinksIfOwnerMatch: シンボリックリンクを許可(所有者が同じ場合のみ)
# -Indexes: ディレクトリ一覧の表示を無効化(セキュリティ対策)
Options +SymLinksIfOwnerMatch -Indexes

# デフォルトで表示するファイルをindex.phpに設定
DirectoryIndex index.php

# mod_rewriteモジュールが利用可能な場合の設定
<IfModule mod_rewrite.c>
   # URLの書き換え機能を有効化
   RewriteEngine On
   
   # ベースとなるURLパスを設定(/laravel-d01/以下のURLに対してルールを適用)
   RewriteBase /laravel-d01/
   
   # ディレクトリ一覧の表示を明示的に無効化(追加のセキュリティ対策)
   Options -Indexes
   
   # publicディレクトリへのアクセスは書き換えずにそのまま通す
   # 例:/laravel-d01/public/css/style.css → そのままアクセス可能
   RewriteRule ^public/ - [L]
   
   # ルートへのアクセス(/laravel-d01/)をpublic/index.phpへ転送
   # [L]フラグで以降のルールは適用しない
   RewriteRule ^$ public/index.php [L]
   
   # 上記以外のすべてのリクエストをpublicディレクトリ配下に転送
   # 例:/laravel-d01/about → /laravel-d01/public/about
   RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

laravel-dir/public/.htaccess

# PHPの設定
AddHandler application/x-httpd-php .php

# 基本設定
Options +SymLinksIfOwnerMatch
DirectoryIndex index.php

# mod_rewriteの設定
<IfModule mod_rewrite.c>
    RewriteEngine On
    
    # 実ファイルが存在する場合はそのまま表示
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    # それ以外はindex.phpにリダイレクト
    RewriteRule ^ index.php [L]
</IfModule>

本番環境にNPMをインストールしない

本番環境では、できるだけサーバー負荷を軽減し、セキュリティリスクも減らすために不要なソフトウェアをインストールしない方が良いです。

NPMやNode.jsは通常、フロントエンドのビルドにしか使わないため、本番環境には必須ではありません。

そのため、開発環境で必要なビルドを完了させ、生成されたファイルのみを本番環境にアップロードすることで、シンプルかつ安全な運用が可能になります。

参考サイト

必ずしも本番環境のサーバーにNPMのインストールは必要ないと思います。
開発環境でNode.jsのビルドを行い、作成されたJavaScriptファイルをアップロードするのも手です。

https://chigusa-web.com/blog/sakura-laravel/
【GTM】サンクスページがないフォームの計測

フォーム送信完了のイベントの作成

タグの作成

  • 名前:問い合わせ完了2
  • タグの種類:Google アナリティクス: GA4 イベント
  • イベント名:generate_lead
  • イベントパラメータ
    • イベントパラメータ:form_type、値:contact2
    • イベントパラメータ:form_complete_count、値:1

トリガーの設定

  • 名前:問い合わせ完了2
  • トリガーのタイプ:フォームの送信
  • 発生場所:一部のフォーム
  • 条件:Page URL 含む p=11243(※該当ページ)

注意)問い合わせが完了していない場合でも送信されればカウントされてしまいます

サンクスページを作成し、イベントの作成をする(プラグインを使用)方法がオススメです

GA4のキーイベントの設定でgenerate_leadを登録して、1回のセッションで1回のカウントを設定していると
キーイベントの回数としては正しくカウントされます

フォーム到達イベントの作成

タグの設定

  • 名前:問い合わせフォーム到達2
  • タグの種類:Google アナリティクス: GA4 イベント
  • イベント名:form_arrival
  • イベントパラメータ
    • イベントパラメータ:form_type、値:contact2
    • イベントパラメータ:form_arrival_count、値:1

トリガーの設定

  • 名前:問い合わせフォーム到達2
  • トリガーのタイプ:要素の表示
  • 選択方法:CSSセレクタ
  • 要素セレクタ:wpcf7-f11247-p11243-o1 > form > p:nth-child(6) > input(※該当のセレクタ)
  • 起動するタイミング:1ページにつき1度
  • 条件:Page URL 含む p=11243(※該当ページ)

要素セレクタの取得

該当要素のうえで右クリック>Copy>Copy selectorで内容をコピーできます


    【Googleタグマネージャー】バナー表示イベント

    バナークリックイベントの作成

    ↓ページ下部のようなIDが付与されているバナーの表示イベントを考えます。

    ▼Googleタグマネージャーの変数より【Click Element】があるか確認、なければ追加します

    タグの作成

    下記記事のボタンAクリックをコピーして作成します

    https://ntorelabo.com/?p=11193

    ▼コピーした内容のイベント名を記事中バナークリック、イベントパラメータのcta_idの値を取得したIDに変更します

    トリガーの作成

    ▼コピーした内容のイベント名を記事中バナークリック、idの値をcta_bnr_a *に変更します

    プレビューで確認

    GA4のレポート>リアルタイムのイベント数より表示を確認し、イベント公開します

    バナー表示イベントの作成

    タグの設定

    • 名前:記事中バナー表示
    • タグの種類:Google アナリティクス: GA4 イベント
    • イベント名:cta_view
    • イベントパラメータ
      • イベントパラメータ:click_id、値:cta_bnr_a
      • イベントパラメータ:cta_view_count、値:1

    トリガーの設定

    • 名前:記事中バナー表示
    • トリガーのタイプ:要素の表示
    • 選択方法:CSSセレクタ
    • 要素セレクタ:#cta_bnr_a
    • 起動するタイミング:1要素につき1度

    ※視認の最小割合…要素の何割が表示されればタグを動かかす(デフォルト50%)

    カスタム定義

    • 指標名:cta_view_count
    • イベントパラメータ:cta_view_count
    • 測定単位標準

    <バナー>

    【CSS】flexボックスでjustify-content: center;だけど子要素は左寄せにしたい場合

    ↑下の行を左寄せにしたい

    display: grid;

    display: flex;ではなくdisplay: grid;にする

    .grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, 80px);
    justify-content: center;
    max-width: 400px;
    grid-gap: 30px;
    background: #f2f2f2;
    padding: 8px;
    }

    参考サイト:https://zenn.dev/kibe/articles/f093495a22b88c

    WordPressでdrawer.js実装

    CDN読み込み

    公式サイト:
    https://git.blivesta.com/drawer

    ▼一部参考

    https://www.miso.blog/jquery-drawer

    公式サイトよりCDNの記述をコピーしてheadタグ内に張り付け

    ▼functions.php

    <?php
    add_action('wp_head', function () {
    ?>
    <!-- drawer.css -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/drawer/3.2.2/css/drawer.min.css">
    <!-- jquery & iScroll -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/iScroll/5.2.0/iscroll.min.js"></script>
    <!-- drawer.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/drawer/3.2.2/js/drawer.min.js"></script>
    <!-- bootstrap(ドロップダウンメニューにするなら必要) -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <?php 
    });

    各ファイルマークアップ

    ▼header.php

    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta name="description" content="<?php bloginfo( 'description' )?>">
      <title><?php bloginfo( 'name' ); ?></title>
      <?php wp_head(); ?>
    </head>
    <body class="drawer drawer--right drawer--navbarTopGutter">
        <header class="drawer-navbar drawer-navbar--fixed" role="banner">
        <div class="drawer-container">
          <div class="drawer-navbar-header">
            <a class="drawer-brand" href="<?php echo home_url(); ?>"><?php bloginfo( 'name' ); ?></a>
            <button type="button" class="drawer-toggle drawer-hamburger">
              <span class="sr-only">toggle navigation</span>
              <span class="drawer-hamburger-icon"></span>
            </button>
          </div>
        </div>    
        <nav class="drawer-nav" role="navigation">
          <!-- メニューの読み込み -->
          <?php wp_nav_menu( array( 
            'theme_location' => 'my-drawer', 
            'menu_class' => 'drawer-menu', 
            'container' => false, 
            'depth' => 1,
            'add_li_class' => 'nav-item', // liタグへclass追加
            'add_a_class' => 'drawer-menu-item' // aタグへclass追加 
            ) ); ?>
        </nav>
        </header>
        <main role="main">

    下記サイトを参考にナビゲーションメニューの要素にクラス付与

    ▼functions.phpに追記

    1. ナビゲーションメニューの要クラス付与のためのフィルターイベント
    2. スタイル調節のためのCSS
    3. Drawerを動かすために、jQueryのコード
    // wp_nav_menuのliにclass追加
    function add_additional_class_on_li($classes, $item, $args)
    {
    if (isset($args->add_li_class)) {
    $classes['class'] = $args->add_li_class;
    }
    return $classes;
    }
    add_filter('nav_menu_css_class', 'add_additional_class_on_li', 1, 3);
    
    // wp_nav_menuのaにclass追加
    function add_additional_class_on_a($classes, $item, $args)
    {
    if (isset($args->add_li_class)) {
    $classes['class'] = $args->add_a_class;
    }
    return $classes;
    }
    add_filter('nav_menu_link_attributes', 'add_additional_class_on_a', 1, 3);
    
    add_action('wp_head', function () {
    ?>
    <!-- drawer.css -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/drawer/3.2.2/css/drawer.min.css">
    <!-- jquery & iScroll -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/iScroll/5.2.0/iscroll.min.js"></script>
    <!-- drawer.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/drawer/3.2.2/js/drawer.min.js"></script>
    <!-- bootstrap(ドロップダウンメニューにするなら必要) -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <style>
    .drawer-navbar {			
    left: 0;
    }
    .drawer-hamburger {
    padding: calc(1.875rem - 13px) .75rem;
    }
    </style>
    <script>
    jQuery(function ($) {
    $(document).ready(function() {
    $('.drawer').drawer();
    });
    });
    </script>
    <?php 
    });

    参考サイト)wp_nav_menuでliやa要素にclassを追加する方法
    https://zenn.dev/minnanowp/articles/823e3eabd24f20

    ▼footer.php

    </main>
    <?php wp_footer(); ?>
    <script>
    jQuery(function ($) {
    $(document).ready(function() {
    $('.drawer').drawer();
    });
    });
    </script>
    </body>
    </html>
    【WordPress】カラーパレット追加方法

    【Wordpress】カラーパレット追加方法

    ▼functions.php

    function my_wp_theme_json_data_theme( $theme_json ){
        $new_data['version'] = 2;
        // カラーパレット カスタマイズ 既存パレットに追加(単色)
        $new_data['settings']['color']['palette'] = array(
            array(
                'name'  => esc_attr__( 'Primary', 'theme_domain' ),
                'slug'  => 'primary',
                'color' => '#f4f4f4',
            ),
            array(
                'name'  => esc_attr__( 'Accent', 'theme_domain' ),
                'slug'  => 'accent',
                'color' => '#cd162c',
            )
        );
        return $theme_json->update_with( $new_data );
    }
    add_filter( 'wp_theme_json_data_theme', 'my_wp_theme_json_data_theme' );

    ▼追加CSS

    .has-primary-color {
    	color: #f4f4f4;
    }
    .has-primary-background-color {
    	background-color: #f4f4f4;
    }
    .has-primary-border-color {
    	border-color: #f4f4f4;
    }
    .has-accent-color {
    	color: #cd162c;
    }
    .has-accent-background-color {
    	background-color: #cd162c;
    }
    .has-accent-border-color {
    	border-color: #cd162c;
    }

    上記の画像ようにデフォルトに追加できまあ

    【Googleタグマネージャー】ボタンのHTML要素ID属性からイベント設定

    クリック対象にID付与する理由

    Googleタグマネージャーでボタンのクリック計測するとき、IDを付与することにより正確に計測が可能です

    WordPress編集画面でボタンにIDを付与する

    <div class="wp-block-snow-monkey-blocks-buttons smb-buttons" id="cta_btn_a"><!-- wp:snow-monkey-blocks/btn -->
    <div class="wp-block-snow-monkey-blocks-btn smb-btn-wrapper"><a class="smb-btn" href=""><span class="smb-btn__label">Button-A</span></a></div>
    <!-- /wp:snow-monkey-blocks/btn --></div>

    Googleタグマネージャーで設定する

    変数の設定

    ▼変数から「Click Element」を選択

    ※「Click Element」…HTMLの要素を取得できます

    タグの設定

    ▼下記の通り設定

    • 名前:ボタンAクリック
    • タグの種類:Googleアナリティクス:GA4イベント
    • 測定ID:GA4測定ID
    • イベント名:cta_click
    • イベントパラメータ
      (ボタンのIDごとにクリック数をカウントできるように設定)
      • cta_id (cta_btn_a)
      • cta_click_count (1)

    トリガーの設定

    • 名前:ボタンAクリック
    • トリガーのタイプ:クリック – すべての要素
    • このトリガーの発生場所:一部のクリック
    • イベント発生時にすべての条件がtrueの場合にこのトリガーを配置します:
      Click Element / CSS セレクタに一致する / #cta_btn_a*
      (※上記ボタンAのHTMLコードを参照)

    入力したら右上の保存をクリック

    プレビューで確認

    上記ボタンAをクリックするとぼたんAクリックがTags Firedに移動することが確認できます

    GAで確認

    「レポート」の「リアルタイム」の「イベント」のカードでcta_clickを確認できます

    さらにcta_clickを開くと設定した各パラメータの表示も確認できます

    カスタム定義の設定

    ▼カスタムディメンションの設定でGTAのイベントパラメータからコピーして貼り付ける

    ▼同様にカスタム指標の設定も下記の通りする

    ※即手単位は「標準」

    【Googleタグマネージャー】内部リンククリックイベント作成手順

    1)組み込み変数の設定

    ▼Googleタグマネージャーで変数を選択し組み込み変数の設定をクリック

    ▼Click URLとClick Textを追加

    2)タグの作成

    タグの設定

    • 名前:内部リンククリック(任意のもの)
    • タグの種類:Google アナリティクス: GA4 イベント
    • イベント名:internal_link_click(任意のもの)
    • イベントパラメータ
      • イベントパラメータ:click_url、値:Click URL
      • イベントパラメータ:click_text、値:Click Text
      • イベントパラメータ:internal_link_click_count、値:1

    トリガーの設定

    • トリガーの名前:内部リンククリック
    • トリガーのタイプ:クリック- リンクのみ
    • このトリガーの発生場所:一部のリンククリック
      Click URL 含む ドメイン

    3)確認

    Googleタグマネージャーのプレビュー

    GTMのプレビューで内部リンククリックがTags Firedに移動されているのを確認

    Googleアナリティクスのイベントでの設定

    ▼Googleアナリティクスで設定を確認
    →レポート→リアルタイム→internal_link_clickを選択

    • イベントパラメータ:click_url、値:Click URL
    • イベントパラメータ:click_text、値:Click Text
    • イベントパラメータ:internal_link_click_count、値:1

    上記項目が確認できます

    カスタムディメンション、カスタム指標の設定

    レポートで表示できるようカスタムディメンション、カスタム指標の設定を設定します

    ▼右下管理ボタンを選択しカスタム定義をクリック

    →Googleタグマネージャーよりイベントパラメータの内容をコピーして貼り付けます

    【Google Tag Manager】サンクスページ到達イベントの作成

    準備

    今回はプラグイン「コンタクトフォーム7」でフォームを作成、サンクスページを下記記事参考で作成しました

    https://wpmake.jp/contents/plugin/contact-form7/thanks-page

    タグの作成

    ▼サイドメニューのタグを選択し新規をクリック

    ▼タグの設定を下記の通り行います

    • タグの名前:問い合わせ完了
    • タグの種類:Google アナリティクス: GA4 イベント
    • 測定ID:GA4測定ID(GA4測定IDで変数に登録済みのものを使用)
    • イベント名:genarate_lead
    • イベントパラメータ
      • form_type contact:同じgenerate_leadで問い合わせで種類を分けたい場合を想定※1つであればなくても問題なし
      • form_complete_count:問い合わせ完了数のための指標

    トリガーの設定

    ▼新規でトリガーを作成していきます

    ▼トリガーの設定を下記の通り行います

    サンクスページのパスと直前のページ(問い合わせフォーム)のパスをそれぞれ設定

    ※referrer…直前のページ

    お問い合わせフォーム到達イベント作成

    問い合わせフォーム到達のイベントの作成も同様にしておき、

    ▼タグの設定

    タグの種類Google アナリティクス: GA4 イベント
    測定IDGoogle アナリティクス測定 ID
    イベント パラメータform_type (contact)
    form_arrival (1)

    ▼トリガーの設定

    トリガーのタイプページビュー
    このトリガーの発生場所一部のページビュー
    イベント発生時にこれらすべての条件が true の場合にこのトリガーを配信しますPage Path 含む 問い合わせフォームページパス

    プレビューでイベント発火を確認

    イベント作成したところプレビューにてイベントが発火しない問題が発生

    ▼WordPress管理画面のメニュー設定のパーマリンクから、パーマリンク構造を「基本」から「投稿名」にして、改めてトリガーのページパスを変更したところ発火しました。

    今まで作成したページのURLの変更が困るため、ほかの解決策としてトリガーの設定で「Page Path」から「Page URL」に変更したところ正しく発火しました

    GoogleアナリティクスGA4

    指標、ディメンション

    • 指標…数字
    • ディメンション…分析軸(指標の切り口)

    代表的な指標

    指標名内容
    アクティブユーザ数ユニークユーザー数
    表示回数ページビュー
    セッションWebサイトへの訪問回数
    エンゲージメント率ユーザーにとって価値のある訪問の割合
    ※10秒以上閲覧 or 2ページ以上閲覧 or CVイベント発生
    イベント数Webサイトで発生したユーザーの行動すべて

    代表的なディメンション

    指標名内容
    年齢、性別
    デバイスカテゴリデスクトップ、モバイル、タブレット
    デフォルトチャネルグループユーザーが訪問した際の大まかな参照元
    (自然検索、他サイトからの訪問、広告)
    ページパスとスクリーンクラスページパスはURLのドメイン部分を除いたもの
    ※スクリーンクラスはアプリのためのディメンション
    ランディングページユーザーがWebサイトに訪れた時に最初に見たページ

    カスタム指標、カスタムディメンション

    もともと備わっていない、独自に設定した指標、ディメンション

    イベント

    Webサイト内でのユーザーの行動
    …訪問、ページビュー、クリック

    • 自動収集イベント
    • 拡張計測機能イベント
    • 推奨イベント
    • カスタムイベント

    自動収集イベント

    イベント名発生タイミング※自動で収集
    first_visitユーザが初めてWebサイトに訪問
    session_startユーザがWebサイトに訪問
    page_viewユーザがページを開いた
    user_engagementWebサイトが選択された状態が1秒以上続いた

    拡張計測機能イベント

    イベント名発生タイミング※自動で収集
    scrollユーザがページの90%地点までスクロールした
    clickユーザが外部リンクをクリック
    view_search_resultsユーザがWebサイト内の検索結果を表示した
    file_downloadユーザがファイルをクリック

    推奨イベント

    自身で登録する必要がある

    決められた名前を使用

    イベント名発生タイミング※自動で計測されない
    genarate_leadユーザがお問い合わせフォームから送信した
    sign_upユーザが会員登録した
    loginユーザがログインした
    purchaseユーザが購入した

    カスタムイベント

    自身で登録する必要がある

    任意の名前を使用

    ↓例

    イベント名※任意…下記は例として発生タイミング※自動で計測されない
    cta_viewユーザがバナーやボタンを表示した
    cta_clickユーザがバナーやボタンクリック
    【Next.js】ライブラリ使わないでカルーセルスライダー

    demo(Next.jsの静的ビルドファイルをiframeで表示したもの)

    Next.jsを使って無限ループ機能付きのシンプルなカルーセルを実装します(画像スライドショーの基本的な機能をおさえつつ、メンテナンスしやすいコードを目指します)

    このカルーセルには以下の機能が含まれています:

    • ✨ 無限ループスライド
    • 🎯 自動再生機能
    • 🎨 矢印ナビゲーション
    • 📍 インジケーター
    • 📱 レスポンシブ対応

    ソースファイル

    my-nextjs-app/
    ├── src/
    │   ├── app/
    │   │   └── page.tsx                    # カルーセルを使用するページ
    │   ├── components/
    │   │   └── SimpleCarousel.tsx          # カルーセルコンポーネント
    │   └── styles/
    │       └── simpleCarousel.module.css   # カルーセル用スタイル

    page.tsx

    /**
     * カルーセルページコンポーネント
     */
    
    import React from 'react';
    import SimpleCarousel from '@/components/simpleCarousel';
    
    export default function CarouselPage() {
      // スライドのデータ定義
      // - 外部のAPIから取得する場合はここを修正
      const slides = [
        {
          id: 1,
          src: "https://picsum.photos/800/400",
          alt: "First slide"
        },
        {
          id: 2,
          src: "https://picsum.photos/800/400?random=1",
          alt: "Second slide"
        },
        {
          id: 3,
          src: "https://picsum.photos/800/400?random=2",
          alt: "Third slide"
        }
      ];
    
      return (
        <div className="container mx-auto p-4">
          <SimpleCarousel 
            slides={slides}
            autoPlayInterval={3000} // 自動再生の間隔(ミリ秒)
            showArrows={true}      // 矢印ナビゲーションの表示
            showIndicators={true}  // インジケーターの表示
          />
        </div>
      );
    }

    simpleCarousel.tsx

    /**
     * シンプルなカルーセルコンポーネント
     * 
     * 特徴:
     * - 無限ループ機能
     * - 自動再生
     * - 矢印ナビゲーション
     * - インジケーター
     * - レスポンシブ対応
     */
    
    'use client'; // クライアントサイドでの実行を指定
    
    import React, { useState, useRef, useEffect, useCallback } from 'react';
    import styles from '@/styles/simpleCarousel.module.css';
    
    // スライドデータの型定義
    interface SlideData {
      id: number;    // スライドの一意のID
      src: string;   // 画像のURL
      alt: string;   // 代替テキスト
    }
    
    // コンポーネントのプロパティの型定義
    interface CarouselProps {
      slides: SlideData[];        // スライドデータの配列
      autoPlayInterval?: number;  // 自動再生の間隔(ミリ秒)
      showArrows?: boolean;      // 矢印ナビゲーションの表示/非表示
      showIndicators?: boolean;  // インジケーターの表示/非表示
    }
    
    const SimpleCarousel: React.FC<CarouselProps> = ({
      slides,
      autoPlayInterval = 3000,
      showArrows = true,
      showIndicators = true
    }) => {
      // State管理
      const [currentSlide, setCurrentSlide] = useState<number>(slides.length);  // 現在のスライドインデックス
      const [isTransitioning, setIsTransitioning] = useState(false);           // トランジション中かどうか
      const slideContainerRef = useRef<HTMLDivElement>(null);                  // スライドコンテナのref
    
      // 無限ループのためのスライド配列を作成(前後に1セットずつ追加)
      const extendedSlides = [...slides, ...slides, ...slides];
    
      // スライド変更のハンドラー(useCallbackでメモ化)
      const handleSlideChange = useCallback((direction: 'next' | 'prev'): void => {
        if (isTransitioning) return;  // トランジション中は処理をスキップ
        
        setIsTransitioning(true);
        if (direction === 'next') {
          setCurrentSlide(prev => prev + 1);
        } else {
          setCurrentSlide(prev => prev - 1);
        }
      }, [isTransitioning]);
    
      // 自動再生のための効果
      useEffect(() => {
        const timer = setInterval(() => {
          handleSlideChange('next');
        }, autoPlayInterval);
    
        // クリーンアップ関数
        return () => clearInterval(timer);
      }, [autoPlayInterval, handleSlideChange]);
    
      // トランジション終了時の処理
      useEffect(() => {
        if (!isTransitioning) return;
    
        const transitionEndHandler = () => {
          setIsTransitioning(false);
          
          // 最後のクローンまで来た場合、最初に戻す
          if (currentSlide >= slides.length * 2) {
            setCurrentSlide(slides.length);
          }
          // 最初のクローンより前に来た場合
          else if (currentSlide < slides.length) {
            setCurrentSlide(slides.length * 2 - 1);
          }
        };
    
        const container = slideContainerRef.current;
        container?.addEventListener('transitionend', transitionEndHandler);
    
        // クリーンアップ関数
        return () => {
          container?.removeEventListener('transitionend', transitionEndHandler);
        };
      }, [currentSlide, slides.length, isTransitioning]);
    
      // 特定のスライドに直接移動する関数
      const goToSlide = (index: number): void => {
        if (isTransitioning) return;
        setIsTransitioning(true);
        setCurrentSlide(index + slides.length);
      };
    
      // 実際のスライドインデックスを計算(表示用)
      const actualSlideIndex = ((currentSlide % slides.length) + slides.length) % slides.length;
    
      return (
        <div className={styles.carousel}>
          <div className={styles.slideContainer} ref={slideContainerRef}>
            {/* スライドラッパー */}
            <div 
              className={styles.slideWrapper}
              style={{ 
                transform: `translateX(-${currentSlide * 100}%)`,
                transition: isTransitioning ? 'transform 0.5s ease-in-out' : 'none'
              }}
            >
              {/* スライドの表示 */}
              {extendedSlides.map((slide, index) => (
                <div 
                  key={`${slide.id}-${index}`} 
                  className={styles.slide}
                  style={{ position: 'relative', overflow: 'hidden', width: '100%', height: '400px' }}
                >
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={slide.src}
                    alt={slide.alt}
                    style={{
                      position: 'absolute',
                      top: 0,
                      left: 0,
                      width: '100%',
                      height: '100%',
                      objectFit: 'cover'
                    }}
                  />
                </div>
              ))}
            </div>
    
            {/* 矢印ナビゲーション */}
            {showArrows && (
              <>
                <button
                  onClick={() => handleSlideChange('prev')}
                  className={`${styles.arrowButton} ${styles.prevButton}`}
                  aria-label="Previous slide"
                  disabled={isTransitioning}
                >
                  ←
                </button>
                <button
                  onClick={() => handleSlideChange('next')}
                  className={`${styles.arrowButton} ${styles.nextButton}`}
                  aria-label="Next slide"
                  disabled={isTransitioning}
                >
                  →
                </button>
              </>
            )}
    
            {/* インジケーター */}
            {showIndicators && (
              <div className={styles.indicators}>
                {slides.map((_, index) => (
                  <button
                    key={index}
                    onClick={() => goToSlide(index)}
                    className={`${styles.indicator} ${
                      actualSlideIndex === index ? styles.indicatorActive : ''
                    }`}
                    aria-label={`Go to slide ${index + 1}`}
                    disabled={isTransitioning}
                  />
                ))}
              </div>
            )}
          </div>
        </div>
      );
    };
    
    export default SimpleCarousel;

    simpleCarousel.module.css

    /* styles/simpleCarousel.module.css */
    .container {
        max-width: 1200px;
        margin: 0 auto;
        padding: 2rem 1rem;
      }
      
      .title {
        font-size: 1.5rem;
        font-weight: bold;
        margin-bottom: 2rem;
      }
      
      .carousel {
        position: relative;
        width: 100%;
        max-width: 48rem;
        margin: 0 auto;
        overflow: hidden;
      }
      
      .slideContainer {
        position: relative;
        overflow: hidden;
        border-radius: 0.5rem;
        aspect-ratio: 2/1;
      }
      
      .slideWrapper {
        position: absolute;
        display: flex;
        width: 100%;
        height: 100%;
      }
      
      .slide {
        flex: 0 0 100%;
        width: 100%;
        height: 100%;
      }
      
      .slide img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
      
      .arrowButton {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        background-color: rgba(255, 255, 255, 0.8);
        border-radius: 50%;
        padding: 0.5rem;
        cursor: pointer;
        border: none;
        z-index: 1;
      }
      
      .arrowButton:hover {
        background-color: rgb(255, 255, 255);
      }
      
      .prevButton {
        left: 1rem;
      }
      
      .nextButton {
        right: 1rem;
      }
      
      .indicators {
        position: absolute;
        bottom: 1rem;
        left: 50%;
        transform: translateX(-50%);
        display: flex;
        gap: 0.5rem;
        z-index: 1;
      }
      
      .indicator {
        width: 0.5rem;
        height: 0.5rem;
        border-radius: 50%;
        background-color: rgba(255, 255, 255, 0.5);
        border: none;
        cursor: pointer;
        padding: 0;
      }
      
      .indicatorActive {
        background-color: rgb(255, 255, 255);
      }

    注意点と対策
    (Hot Module Replacement: HMR)に関連するエラー

    Next.jsの開発環境でのホットリロード(Hot Module Replacement: HMR)に関連するエラーが発生します。

    エラーの原因

    1. CSSモジュールを使用している際に、HMRがCSSファイルを更新しようとする
    2. 古いスタイルシートを削除しようとする際に、すでに要素が削除されているためエラーが発生
      (無限にスライド流れるようクローンを作成する際の記述)

    対策

    グローバルCSSとして管理

    /* globals.css */
    .carousel { ... }

    CSS-in-JSライブラリの使用

    import styled from 'styled-components';

    next.config.jsでの設定

    module.exports = {
    webpack: (config) => {
    // HMRの設定をカスタマイズ
    return config;
    }
    }
    【WordPress】アクションフック、フィルターフック使用方法

    アクションフックとは

    処理の追加が可能です

    functions.php で add_action や add_filter を記述していきます

    ※本サイトはWPcodeにて行いました

    参考サイト:https://idasalon.com/?p=250#index_id3

    add_action('フック名', function () {
        実行する処理
    });

    ↓実際このページでコンテンツ開始部分に表示

    add_action('arkhe_before_entry_content', function () {
        if (is_single(10922)) {
        ?>
        <p style="font-size: 1.2rem; background: #eee; padding: 4px 10px;">※アクションフックにて表示しています</p>
        <?php
        }
    });

    https://arkhe-theme.com/ja/manual/hooks

    https://arkhe-theme.com/ja/manual/hooks

    フロントページにタグクラウドを追加

    フックを使えば「ホームページの表示」を「最新の投稿」にしていてもカスタマイズできます

    add_action('arkhe_start_front_main', function () {
    	$args = array(
    		'smallest' => 1,
    		'largest' => 1,
    		'unit' => 'em',
    		'number' => 30,
    		'orderby' => 'count',
    		'order' => 'DESC',
    		'format' => 'list'
    	);
    	$args['taxonomy'] = array('post_tag','category');
    	wp_tag_cloud( $args );
    	?>
    	<style>
    		ul.wp-tag-cloud {
    			display: flex;
    			flex-wrap: wrap;
    			margin-bottom: 2.5rem;
    			gap: 8px;
    			padding-left: 0;
    		}
    		.wp-tag-cloud li {
    			list-style: none;
    		}
    		.wp-tag-cloud li a {
    			background: #f7f7f7;
    		}
    	</style>
    	<?php
    });
    https://norando.net/wordpress-tag-cloud
    「Googleタグマネージャー」アカウントを作る→「GA4」を設定する方法

    Google Tag Manager(GTM)とは

    Google Tag Managerで扱うタグとはWebサイトとマーケティングツール間で情報をやりとりするためのコードです

    Googleアナリティクス、Google広告など、、

    <script></script>のような形式で記述される場合が多いです

    Googleタグマネージャーを使用すればhtmlの編集をせずにタグの管理が可能です

    タグ:タグ
    トリガー:タグを動かすきっかけ
    変数:タグに追加で情報を設定

    GTMアカウント作成

    Googleタグマネージャーで検索

    アカウントの各項目を設定

    • アカウントは会社名や個人を特定できるもの
    • コンテナはドメイン名(Webサイトごとに作成する場合があります)

    【Google拡張機能】Tag Assistant Companion

    • タグの動作確認
    • Googleタグマネージャーのプレビュー機能使用時に開発者ツールが使える

    ※Tag Assistant Legacyのサポートが終了したためTag Assistant Companionを使用

    【Google拡張機能】Adswerve

    Googleタグマネージャーの仮想環境を作れる(管理権限のないサイトでも可能)

    【WordPressサイト】Googleタグマネージャー導入方法

    方法(1)プラグイン「GTM4WP」での設定方法

    1)GTM4WPをインストール

    新規プラグイン追加で「gtm4wp」と検索

    2)GoogleタグマネージャーIDを張り付ける

    Container code ON/OFFがバグでOFFになるので、ONにして再度保存しなおす

    方法(2)プラグイン「WPcode」での設定方法

    ▽Googleタグマネージャーより貼り付けるコードをコピー

    ▽ワードプレス管理画面の「コードスぺニット」→「ヘッダーとフッター」をクリックして、コピーした内容を張り付け

    ※オリジナルテーマの仕様等WordPressをカスタムしている場合「wp_head()」「wp_body_open()」がないと挿入されません

    How To Add Google Tag Manager To WordPress 
    https://wpcode.com/how-to-add-google-tag-manager-to-wordpress

    GoogleタグマネージャーにGA4を設定する方法

    1)GA4のアカウント、プロパティを作成する

    https://ntorelabo.com/?p=10699#i

    2)GA4の測定IDを定数に登録する

    「GA4の測定ID」とは

    イベントの設定で非常に使用します

    →定数でGTMに登録しワンクリックで使えるようにしておくと便利です

    〇Googleアナリティクスで測定IDを確認

    ↓Googleアナリティクスで「管理(歯車アイコン)」→「データストリーム」クリックすると詳細内容に測定IDが表示されます

    〇Googleタグマネージャーの画面で「定数」として登録

    ↓「変数」→「新規」をクリック

    ↓Googleタグマネージャーの画面で変数として登録

    ↓定数を選択

    ↓測定IDを張り付ける

    3)「GA4設定タグ」を作成

    「GA4設定タグ」とは

    • イベント計測の基本となるタグ
    • 計測するすべてのページで発火

    GA4設定タグ作成手順

    サイドのメニューからタグから新規を選択

    タグのタイプを「Googleアナリティクス」「Googleタグ」選択

    先ほど変数に登録したGoogleアナリティクスの測定IDを選択

    トリガーは「Initialization – All Pages」を選択

    (公式推奨)Googleアナリティクスのタグは全てのページに埋め込む必要があるため

    (参考サイト)
    [GTM] GA4設定タグとイベントタグの関係
    https://ayudante.jp/column/2023-07-14/12-00

    公開で設定完了

    Googleアナリティクス導入

    Googleアナリティクスとは

    無料で使用可能で、非常に高機能なツールです。

    サイト全体のアクセス数、ページ別、流入元の状況など、数多くのデータが確認できます。

    UAとGA4

    GA4(第四世代)が2020年登場、UA(従来のGoogleアナリティクス)は2023年7月にサポートが終了しました。

    • UAはWebサイトのページ単位の計測
    • GA4はアクセス解析がユーザー中心 例)複数デバイスでもユーザを認識可能

    導入手順

    Googleアナリティクスアカウントの作成(事前にGoogleアカウントの作成外必要)

    データ保持期間を14か月に変更する

    プロパティの設定

    アカウント名会社名、名前(半角アルファベット)
    プロパティ名分析したいサイト(ドメイン)の名前
    ※Webサイト単位
    レポートのタイムゾーン国内向けのサイトの場合日本に変更
    通貨国内向けのサイトの場合日本円に変更

    データストリームの設定

    データストリーム…分析するプラットフォーム、ひとつのサービス内でWebサイト、アプリを区別できる

    ウェブサイトのURLアクセス解析を行いたいサイトのURL
    ストリーム名サイトの名称

    データストリームの作成後測定IDが確認できます。

    トラッキングコード、測定IDについて

    種別書式概要
    トラッキングIDUA-XXXXXXXプロパティを一意に特定するID
    Googleアナリティクスでデータを計測するためにはトラッキングIDが必須
    UAプロパティの計測時に活用するID
    測定IDG-XXXXXXXGA4プロパティの計測時に活用するID

    GA4のアカウント構造

    アカウント1つのアカウントで、最大で50個のプロパティ
    プロパティ1つのWebサイトにつき1つ設定
    プロパティごとに、トラッキングIDが発行されます
    データストリーム複数作成することもできますが、基本的には1つだけ作成

    両方作成しておくことをオススメします

    ▼トラッキングコード現在取得できない?

    プラグイン「Site Kit by Google」

    プラグインをインストール有効化するとセットアップを開始のボタンが表示されます

    ▼アクセスできる情報はすべてチェック

    「Googleサーチコンソール」の設定も済ませてくれています。

    サブディレクトリの解析

    GA4ではUAにあった「ビュー」機能がありません。

    →サブディレクトリのみの解析をしたい場合、サブディレクトリのサイトごとにプロパティを分けてする方法があります。

    ホームページ制作の流れ

    ホームページ制作フロー

    • ホームページ作成の依頼をうける
    • 業務内容をヒアリングする
      • サーバ契約、ドメインの取得
      • ワイヤーフレーム、デザインカンプ、参考のサイト、ロゴ、画像、テキストの有無
    • 制作の流れを共有確認
    • デザインがない場合
      • 既にWordPressをインストールしてあり、WordPressログイン情報、FTP情報を教えていただき制作に入る。

    Webサイトが表示される仕組み

    1. WebブラウザからURLを指定
    2. DNSサーバーがドメイン名からIPアドレス

    サーバーとドメイン

    ドメインとは

    ドメインは英語で「領土」「領域」「範囲」を意味しており、Web上での住所といえます。

    ドメインとURLの違い

    URLとは、インターネット上にアップされたすべてのウェブサイトにはURLがあてられており、ブラウザ上でURLを入力することにより、サイトの閲覧が可能になります。

    WebサイトのURLは基本的に以下の3つの要素から構成されています。

    • スキーム:https://
    • ドメイン:○○○.com
    • サブディレクトリ:?p=10440

    https://ntorelabo.com/?p=10440

    URLの核となる部分がドメイン

    独自ドメインとサブドメイン

    独自ドメインは、基本的に同じ名前のものは存在せず、取得後に変更することもできません。サブドメインとは、独自ドメインを分割する場合に使用されます。

    例)Yahoo!ニュース

    Yahoo!のURLをみてみると「https://www.yahoo.co.jp/」の「yahoo.co.jp」にあたる部分が独自ドメインとなります。

    一方Yahoo!ニュースでは「https://news.yahoo.co.jp/」というドメイン名になっていて、独自ドメイン「yahoo.co.jp」に加えて「news」が追加されていることがわかります。この「news」にあたる部分がサブドメインになります。

    https://news.yahoo.co.jp/
         ↑サブドメイン

    独自ドメインの活用法

    • 専用のメールアドレスをりようできる
    • SEOで有利に評価される

    サブドメインの活用方法

    • 1つの独自ドメインの下で複数のWebサイトを運用できる → ドメイン費用を抑えることが可能

    サブドメインとサブディレクトリ

    【本体ドメイン】…○○○.com
    【サブディレクトリ】…○○○.com/△△/
    【サブドメイン】…△△△.○○○.com

    サブディレクトリ
    サブドメイン
    https://help.sakura.ad.jp/domain/2149/?_gl=1%2Agpspir%2A_gcl_aw%2AR0NMLjE3MTEzNDExNTQuQ2p3S0NBandudi12QmhCZEVpd0FCQ1lRQXliN081cTQ4Rko3dUp2TUhSOUlsZE8zajR6RExHT1ZXZnZiME5ZeE43dW02UTBRajFabUxCb0NxTEVRQXZEX0J3RQ..%2A_gcl_au%2ANTQyNzUyNTA4LjE3MDk1MTI5NjY.
    React でアプリ作成

    StackBlitz

    githubで認証試すが利用できない

    JavaScriptにてtodoアプリ

    未完了のTODO

    完了のTODO

    React VSCode インストール

    参考記事:https://teto-tech.com/article/react-start1

    Node.jsのインストール

    ▼「my-app」を作成 → この中に環境が構築

    npx create-react-app my-app 

    ※作業フォルダにてコマンド実行しました

    ▼作業フォルダを移動

    cd my-app

    ▼編集をリアルタイムで確認

    npm start

    my-app/src/App.jsを編集すると正しく表示されました
    ※Ctrl+Cで終了

    Props分割代入

    分割代入しない場合

    export const Profile = (props) => {
     return (
      <p>私の名前は{props.name}です。{props.age}歳です。</p>
     )

    分割代入する場合

    export const Profile = (props) => {
     // propsを分割代入
     const { name, age } = props;
     return (
      <p>`私の名前は{name}です。{age}歳です。`</p>
     )

    ↓引数propsを渡す段階で分割代入

    export const Profile = ({ name, age }) => {
     return (
      <p>`私の名前は{name}です。{age}歳です。`</p>
     )

    useEffect

      useEffect(() => {
        …
      },[num, ]);

    第二引数に変更がある場合、中の処理が実行

    Reactで作成したアプリをレンタルサーバに公開する方法

    参考サイト:https://zenn.dev/kiriyama/articles/538face511307d

    ▼package.jsonを編集

    homepageという項目を追加しURLを記載

    {
      "homepage": "https://○○",
      "name": "my-app",
      "version": "0.1.0",
      "private": true,
    //省略
    }

    ▼publickフォルダに.htaccessのファイルを作成

    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.html [QSA,L]

    ▼コマンド実行

    npm run build

    作成されたbuildフォルダの中身をアップロード
    ※buildフォルダはアップロードしない

    なぜデプロイ時にnpm run buildが必要なのか?
    https://qiita.com/bell_007/items/e84cd7a11b1d196e8bb4

    デモページ

    →実際Reactにて作成したページ

    【@wordpress/scripts】でインライン単位で文字サイズ色を変更できる(リッチテキストツールバー)オリジナルブロック作成

    パッケージインストール

    npm プロジェクトの初期化

    package.json ファイルを作成します。

    npm init -y

    @wordpress/scriptsのインストール

    (WordPress のブロックエディター用のパッケージ)

    npm install @wordpress/scripts @wordpress/blocks @wordpress/i18n @wordpress/block-editor @wordpress/components @wordpress/data react react-dom

    package.jsonにスクリプトが追記

    {
      "name": "my-theme-custom-block",
      "version": "1.0.0",
      "description": "My first WordPress custom block in a theme",
      "main": "build/index.js",
      "scripts": {
        "build": "wp-scripts build",
        "start": "wp-scripts start"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@wordpress/scripts": "^x.x.x"
      }
    }

    @wordpress パッケージの型定義ファイルインストール

    npm install --save-dev @types/wordpress__blocks
    npm install --save-dev @types/wordpress__block-editor @types/wordpress__components
    npm install @wordpress/data @wordpress/rich-text
    npm install --save-dev @types/react @types/wordpress__rich-text

    webpack

    • ES6+やTypeScriptのコードを古いブラウザでも動作するES5に変換できます。
    • モジュール間の依存関係を自動的に解析し、複数のJavaScriptファイルを1つのファイルにまとめます。
    webpackでのTypeScript処理フロー TypeScript .ts ファイル ts-loader TypeScript → JS Babel ES6+ → ES5 出力 bundle.js

    webpack.config.jsの設定

    webpack.config.jsは、webpackの設定ファイルです。

    webpack.config.js の主要構造 entry アプリケーションの 開始点を指定 output バンドルファイルの 出力先と名前を指定 module.rules ファイルの変換方法を ローダーで指定 plugins 追加の処理や最適化を プラグインで指定 resolve モジュールの解決方法を カスタマイズ mode development, production などの環境を指定

    webpack.config.js

    const defaultConfig = require('@wordpress/scripts/config/webpack.config');
    const path = require('path');
    
    module.exports = {
        ...defaultConfig,
    
        // エントリーポイントの設定
        entry: {
            lead: path.resolve(__dirname, 'wp-content/themes/originaltheme/src/lead/index.tsx'),
        },
    
        // 出力の設定
        output: {
            path: path.resolve(__dirname, 'wp-content/themes/originaltheme/build'),
            filename: '[name].js', // [name] には entry で指定したキーが入る
        },
    
        // ファイルの拡張子を省略できるようにする
        resolve: {
            extensions: ['.ts', '.tsx', '.js']
        },
    
    
        module: {
    
            // ローダーの設定
            rules: [
                {
                    test: /\.tsx?$/,
                    use: 'ts-loader',
                    exclude: /node_modules/
                }
            ]
        }
    };
    npm install ts-loader --save-dev

    tsconfig.json

    {
      "compilerOptions": {
        "target": "es5",                          // 出力するJavaScriptのバージョン
        "module": "commonjs",                     // モジュールシステム
        "strict": true,                           // 厳格な型チェックオプション
        "esModuleInterop": true,                  // ESモジュールとの互換性
        "skipLibCheck": true,                     // ライブラリの型チェックをスキップ
        "forceConsistentCasingInFileNames": true, // ファイル名の大文字小文字の一貫性を強制
        "jsx": "react",                           // JSXのサポート
        "moduleResolution": "node",               // モジュール解決方法
        "resolveJsonModule": true,                // JSONモジュールのインポートを許可
        "outDir": "./build",                      // 出力ディレクトリ
        "rootDir": "./wp-content/themes/originaltheme/src" // ソースファイルのルートディレクトリ
      },
      "include": [
        "wp-content/themes/originaltheme/src/**/*" // コンパイル対象のファイル
      ],
      "exclude": [
        "node_modules"                            // コンパイル対象外のファイル
      ]
    }

    ブロックのソースファイルを作成

    リッチテキストツールバーを使用

    インライン単位で文字サイズ文字色を変更できるブロック

    index.tsx

    import { registerBlockType } from '@wordpress/blocks';
    import { __ } from '@wordpress/i18n';
    import {
        useBlockProps,
        RichText,
        RichTextToolbarButton,
    } from '@wordpress/block-editor';
    import {
        registerFormatType,
        applyFormat,
        removeFormat,
        type RichTextValue
    } from '@wordpress/rich-text';
    import React from 'react';
    
    // ブロックの属性の型定義
    interface BlockAttributes {
        content: string;
    }
    
    // フォーマットの型定義
    interface FormatProps {
        isActive: boolean;
        value: RichTextValue;
        onChange: (value: RichTextValue) => void;
    }
    
    // WPFormat の型定義
    interface WPFormatType {
        name: string;
        title: string;
        tagName: string;
        className: string;
        interactive: boolean;
        edit: (props: FormatProps) => JSX.Element;
    }
    
    // フォーマット名の定義
    const FONT_SIZE_FORMAT = 'custom-format/font-size';
    const TEXT_COLOR_FORMAT = 'custom-format/text-color';
    
    // フォントサイズフォーマットの登録
    const fontSizeFormat: WPFormatType = {
        name: FONT_SIZE_FORMAT,
        title: __('Font Size', 'custom-format'),
        tagName: 'span',
        className: 'custom-font-size',
        interactive: false,
        edit: ({ isActive, value, onChange }: FormatProps) => {
            const fontSizes = ['0.75rem', '1rem', '2rem', '3rem', '4rem'];
    
            // フォントサイズの変更の処理の関数
            const onChangeFontSize = (size: string) => {
                const newFormat = {
                    type: FONT_SIZE_FORMAT,
                    attributes: {
                        style: `font-size: ${size};`,
                    },
                };
    
                if (isActive) {
                    onChange(removeFormat(value, FONT_SIZE_FORMAT));
                }
                onChange(applyFormat(value, newFormat));
            };
    
            return (
                <React.Fragment>
                    {fontSizes.map((size) => (
                        <RichTextToolbarButton
                            key={size}
                            icon="editor-textcolor"
                            title={`${size} ${__('Font Size', 'custom-format')}`}
                            onClick={() => onChangeFontSize(size)}
                            isActive={isActive}
                        />
                    ))}
                </React.Fragment>
            );
        }
    };
    
    // 文字色フォーマットの登録
    const textColorFormat: WPFormatType = {
        name: TEXT_COLOR_FORMAT,
        title: __('Red Text', 'custom-format'),
        tagName: 'span',
        className: 'custom-text-color',
        interactive: false,
        edit: ({ isActive, value, onChange }: FormatProps) => {
    
            // 文字色の変更の処理の関数
            const onToggleColor = () => {
                if (isActive) {
                    onChange(removeFormat(value, TEXT_COLOR_FORMAT));
                } else {
                    const newFormat = {
                        type: TEXT_COLOR_FORMAT,
                        attributes: {
                            style: 'color: red;',
                        },
                    };
                    onChange(applyFormat(value, newFormat));
                }
            };
    
            return (
                <RichTextToolbarButton
                    icon="editor-textcolor"
                    title={__('Red Text', 'custom-format')}
                    onClick={onToggleColor}
                    isActive={isActive}
                />
            );
        }
    };
    
    // フォーマットの登録
    registerFormatType(FONT_SIZE_FORMAT, fontSizeFormat);
    registerFormatType(TEXT_COLOR_FORMAT, textColorFormat);
    
    // ブロックを登録
    registerBlockType<BlockAttributes>('customtheme/cardlead', {
        title: __('カード記事リード文', 'custom-block'),
        icon: 'editor-textcolor',
        category: 'text',
    
        attributes: {
            content: {
                type: 'string',
                source: 'html',
                selector: 'p',
            },
        },
    
        edit: ({ attributes, setAttributes }) => {
            const { content } = attributes;
            const blockProps = useBlockProps({
                className: 'my-custom-class',
                style: {
                    borderTop: '8px solid #ffda00',
                    borderBottom: '8px solid #ffda00',
                    textAlign: 'center' as 'center',
                }
            });
    
            return (
                <div {...blockProps}>
                    <RichText
                        tagName="p"
                        value={content}
                        onChange={(newContent: string) => setAttributes({ content: newContent })}
                        placeholder={__('Select text and choose font size or color...', 'custom-block')}
                        allowedFormats={[
                            'core/bold',
                            'core/italic',
                            FONT_SIZE_FORMAT,
                            TEXT_COLOR_FORMAT
                        ]}
                    />
                </div>
            );
        },
    
        save: ({ attributes }) => {
            const { content } = attributes;
            const blockProps = useBlockProps.save({
                className: 'my-custom-class',
                style: {
                    borderTop: '8px solid #ffda00',
                    borderBottom: '8px solid #ffda00',
                    textAlign: 'center' as 'center',
                }
            });
    
            return (
                <div {...blockProps}>
                    <RichText.Content
                        tagName="p"
                        value={content}
                    />
                </div>
            );
        },
    });

    functions.phpで読み込み

    functions.php

    <?php
    // カスタムブロックの登録
    function my_theme_custom_block_init() {
        // register_block_type()の第一引数は「ドメイン名/ブロック名」でregisterBlockType()の第一引数と一致させる
        register_block_type( 'customtheme/cardlead', array(
            'editor_script' => 'cardlead-script',
        ) );
    }
    add_action( 'init', 'my_theme_custom_block_init' );
    
    // ブロックのスクリプトを読み込む
    function my_theme_custom_block_enqueue_assets() {
        $asset_file_cardlead = include( get_template_directory() . '/build/cardlead.asset.php' );
    
        wp_enqueue_script(
            'cardlead-script',
            get_template_directory_uri() . '/build/cardlead.js',
            $asset_file_cardlead['dependencies'],
            $asset_file_cardlead['version']
        );
    }
    add_action( 'enqueue_block_editor_assets', 'my_theme_custom_block_enqueue_assets' );
    LaravelにてECサイト作成 ログイン情報付与 Bladeコンポーネント Stripe決済

    Laravel基礎

    Laravelのルーティングについてweb.phpの使い方(src/routes/web.php)

    • URLとどのファイルを表示させるか紐づけます
    • URLパラメータの受け取りをします

    Laravelルーティングの処理パターン routes/web.php ブラウザリクエスト 直接View返却 Controller処理 クロージャ処理 パターン1: 直接ビュー表示 パターン2: Controller経由 パターン3: クロージャで処理

    Laravelコントローラーの役割

    Laravelでは、ルートで処理されるリクエストの処理を、コントローラーに記述します。

    artisanコマンドでコントローラーを作成

    # 基本的なコントローラー作成
    php artisan make:controller UserController

    ▼app/Http/Controllers/UserController.phpが作成されます

    namespace App\Http\Controllers;  // 名前空間の自動設定
    
    class UserController extends Controller  // クラスの自動生成
    {
        // 基本的なメソッド(--resourceオプション使用時)
        public function index() { }    // 一覧表示
        public function show($id) { }  // 詳細表示
    }
    artisanコマンドの動作 $ php artisan make:controller UserController app/Http/Controllers/ UserController.php コントローラークラスの自動生成完了
    • app/Http/Controllersディレクトリに新しいファイルを作成
    • 基本的なクラス構造を自動生成
    • 必要な名前空間とクラスのインポートを設定

    laravelインストール

    ▼バージョン確認(php composer node.js npm)

    ※MAMP/htdocs/作業フォルダにて

    PS C:\MAMP\htdocs\step01> php -v
    PHP 8.2.9 (cli) (built: Aug  1 2023 12:41:16) (NTS Visual C++ 2019 x64)
    Copyright (c) The PHP Group
    Zend Engine v4.2.9, Copyright (c) Zend Technologies
    PS C:\MAMP\htdocs\step01> composer --version
    Composer version 2.7.1 2024-02-09 15:26:28
    PS C:\MAMP\htdocs\step01> node -v
    v18.17.1
    PS C:\MAMP\htdocs\step01> npm -v
    9.6.7

    参考サイト:https://readouble.com/

    https://readouble.com/laravel/11.x/ja/installation.html

    ▼Composerのcreate-projectコマンドで新しいLaravelプロジェクトを作成

    PS C:\MAMP\htdocs\step01> composer create-project laravel/laravel umarche "8.*" --prefer-dist
    ※umarcheというフォルダを作成

    ▼umarcheに移動しサーバを起動

    PS C:\MAMP\htdocs\step01> cd umarche
    PS C:\MAMP\htdocs\step01\umarche> php artisan serve
    Starting Laravel development server: http://127.0.0.1:8000
    [Tue Apr  2 10:37:07 2024] PHP 8.2.9 Development Server (http://127.0.0.1:8000) started

    →記載されているURLにて表示を確認

    初期設定確認

    DB

    PHPMYADMIN

    ▼MAMP PREFERENCES Ports

    AMP PREFERENCES Ports

    • apache port:8888
    • mysql port: 8889

    Open WebStart Page → TOOLS → PHPMYADMIN

    日本語に設定Appearance settings

    データベース名:laravel_umarcheでデータベースを新規作成

    ▼ユーザ登録

    • Privileges(特権)タブを選択
    • Add user account
      • ユーザ名:umarche
      • ホスト名:%
      • パスワード:pas123
      •  Grant all privileges on database laravel\_umarche.にチェックが入っているか確認
    • go(実行)→ユーザが追加される

    laravel側で記載

    ▼umarch/.env

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=8889
    DB_DATABASE=laravel_umarche
    DB_USERNAME=umarche
    DB_PASSWORD=pas123

    ▼接続を確認

    PS C:\MAMP\htdocs\step01\umarche> php artisan migrate
    Migration table created successfully.
    Migrating: 2014_10_12_000000_create_users_table
    Migrated:  2014_10_12_000000_create_users_table (161.48ms)
    Migrating: 2014_10_12_100000_create_password_resets_table
    Migrated:  2014_10_12_100000_create_password_resets_table (155.42ms)
    Migrating: 2019_08_19_000000_create_failed_jobs_table
    Migrated:  2019_08_19_000000_create_failed_jobs_table (179.04ms)
    Migrating: 2019_12_14_000001_create_personal_access_tokens_table
    Migrated:  2019_12_14_000001_create_personal_access_tokens_table (419.47ms)
    https://coinbaby8.com/access_denied.html

    GitHubでリポジトリを作成

    Gitのインストール

    https://git-scm.com

    コマンドプロンプトを起動しインストールを確認
    ※Windowsにて

    C:\Users\xxxx>git --version 
    git version 2.44.0.windows.1

    ※VSCodeのターミナルの場合インストール後一度開きなおす必要があるかも

    github Create a new repository

    Repository name*:
    laravel_umarche2

    VSCodeターミナルで下記コマンド

    • git init
    • git add -A
    • git add README.md git commit -m “first commit”
    • git branch -M main
    • git remote add origin git@github.com:idatokiya/laravel_umarche2.git
    • git push -u origin main
      エラーメッセージ対処→https://ntorelabo.com/?p=7427#co-index-5

    初期設定

    ブランチを分けて作業
    →VSCodeターミナル下記コマンド

    PS C:\MAMP\htdocs\step01\umarche> git switch -c sec01_initialSetting
    Switched to a new branch 'sec01_initialSetting'
    PS C:\MAMP\htdocs\step01\umarche> git branch
      main
    * sec01_initialSetting

    タイムゾーン 言語設定

    config/app.phpを編集

        /*
        |--------------------------------------------------------------------------
        | Application Timezone
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default timezone for your application, which
        | will be used by the PHP date and date-time functions. We have gone
        | ahead and set this to a sensible default for you out of the box.
        |
        */
    
        'timezone' => 'Asia/Tokyo',
    
        /*
        |--------------------------------------------------------------------------
        | Application Locale Configuration
        |--------------------------------------------------------------------------
        |
        | The application locale determines the default locale that will be used
        | by the translation service provider. You are free to set this value
        | to any of the locales which will be supported by the application.
        |
        */
    
        'locale' => 'Ja',
    

    デバッグバーインストール

    composer require barryvdh/laravel-debugbar

    →composer.jsonにて確認

        "require": {
            "php": "^7.3|^8.0",
            "barryvdh/laravel-debugbar": "^3.7",
            "fruitcake/laravel-cors": "^2.0",
            "guzzlehttp/guzzle": "^7.0.1",
            "laravel/framework": "^8.75",
            "laravel/sanctum": "^2.11",
            "laravel/tinker": "^2.5"
        },

    コミット

    git add -Aでwarning

    PS C:\MAMP\htdocs\step01\umarche> git add -A
    warning: in the working copy of 'composer.json', LF will be replaced by CRLF the next time Git touches it
    warning: in the working copy of 'composer.lock', LF will be replaced by CRLF the next time Git touches it
    warning: in the working copy of 'config/app.php', LF will be replaced by CRLF the next time Git touches it
    warning: in the working copy of 'storage/debugbar/.gitignore', LF will be replaced by CRLF the next time Git touches it

    →対応
    参考サイト:https://qiita.com/WebEngrChild/items/133484ca79fc90a207d5

    git config --global core.autoCRLF false

    ▼再度git add -A

    PS C:\MAMP\htdocs\step01\umarche> git add -A
    PS C:\MAMP\htdocs\step01\umarche> git commit -m "initialSetting" 
    [sec01_initialSetting 6e98bfa] initialSetting
     4 files changed, 158 insertions(+), 3 deletions(-)
     create mode 100644 storage/debugbar/.gitignore
    PS C:\MAMP\htdocs\step01\umarche> git push origin sec01_initialSetting
    Enumerating objects: 13, done.
    Counting objects: 100% (13/13), done.
    Delta compression using up to 12 threads
    Compressing objects: 100% (7/7), done.
    Writing objects: 100% (7/7), 1.68 KiB | 858.00 KiB/s, done.
    Total 7 (delta 5), reused 0 (delta 0), pack-reused 0 (from 0)
    remote: Resolving deltas: 100% (5/5), completed with 5 local objects.
    remote: 
    remote: Create a pull request for 'sec01_initialSetting' on GitHub by visiting:
    remote:      https://github.com/idatokiya/laravel_umarche2/pull/new/sec01_initialSetting
    remote: 
    To github.com:xxx/laravel_umarche2.git
     * [new branch]      sec01_initialSetting -> sec01_initialSetting
    PS C:\MAMP\htdocs\step01\umarche> 

    Viteの採用について

    LaravelのビルドツールがLaravel MixViteに変更(2022/6/28~)

    Laravel Breezeインストール

    Laravel Breezetとは認証ライブラリのひとつで、ログイン、ユーザ登録、パスワードリセット、メールの検証、パスワードの確認などの認証機能をシンプルに実装できます。

    Tailwind CSSを使用します。

    ▼Gitのブランチ変更

    PS C:\MAMP\htdocs\step01\umarche> git switch -c sec02_larabelBreeze
    Switched to a new branch 'sec02_larabelBreeze'
    PS C:\MAMP\htdocs\step01\umarche> git branch
      main
      sec01_initialSetting
    * sec02_larabelBreeze
    PS C:\MAMP\htdocs\step01\umarche> 

    ▼composerでLaravel Breezeのパッケージをインストール

    composer require laravel/breeze "1.*" --dev

    PS C:\MAMP\htdocs\step01\umarche> composer require laravel/breeze "1.*" --dev
    ./composer.json has been updated
    Running composer update laravel/breeze
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 1 install, 0 updates, 0 removals
      - Locking laravel/breeze (v1.10.0)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Nothing to install, update or remove
    Package fruitcake/laravel-cors is abandoned, you should avoid using it. No replacement was suggested.
    Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
    Generating optimized autoload files
    > Illuminate\Foundation\ComposerScripts::postAutoloadDump
    > @php artisan package:discover --ansi
    Discovered Package: barryvdh/laravel-debugbar
    Discovered Package: facade/ignition
    Discovered Package: fruitcake/laravel-cors
    Discovered Package: laravel/breeze
    Discovered Package: laravel/sail
    Discovered Package: laravel/sanctum
    Discovered Package: laravel/tinker
    Discovered Package: nesbot/carbon
    Discovered Package: nunomaduro/collision
    Package manifest generated successfully.
    80 packages you are using are looking for funding.
    Use the `composer fund` command to find out more!
    > @php artisan vendor:publish --tag=laravel-assets --ansi --force
    No publishable resources for tag [laravel-assets].
    Publishing complete.
    No security vulnerability advisories found.

    ▼アセットをコンパイル

    PS C:\MAMP\htdocs\step01\umarche> php artisan breeze:install
    Breeze scaffolding installed successfully.
    Please execute the "npm install" && "npm run dev" commands to build your assets.
    
    PS C:\MAMP\htdocs\step01\umarche> npm install               
    npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
    npm WARN deprecated @babel/plugin-proposal-object-rest-spread@7.20.7: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
    
    added 805 packages, and audited 806 packages in 34s
    
    102 packages are looking for funding
      run `npm fund` for details
    
    1 moderate severity vulnerability
    
    To address all issues (including breaking changes), run:
      npm audit fix --force
    
    Run `npm audit` for details.
    PS C:\MAMP\htdocs\step01\umarche> npm run dev               
    
    > dev
    > npm run development
    
    > development
    > mix
    
    ● Mix █████████████████████████ emitting (95%)
     emit
    
    ● Mix █████████████████████████ done (99%) plugins
     WebpackBar:done
    
    ✔ Mix
      Compiled successfully in 3.27s
                             
       Laravel Mix v6.0.49   
                       
    ✔ Compiled Successfully in 3254ms
    ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────┐
    │                                                                                                                                        File │ Size     │
    ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
    │                                                                                                                                  /js/app.js │ 707 KiB  │
    │                                                                                                                                 css/app.css │ 31.8 KiB │
    └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────┘

    php artisan serveで表示を確認するとLogin Registerの追加を確認

    問題)Login Register画面の表示がおかしい(CSSがあたっていない)

    参考コード:https://github.com/aokitashipro/laravel_umarche/blob/main/resources/views/layouts/app.blade.php

    ▼resources/views/layouts/guest.blade.phpを編集

    <!DOCTYPE html>
    <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta name="csrf-token" content="{{ csrf_token() }}">
    
            <title>{{ config('app.name', 'Laravel') }}</title>
    
            <!-- Fonts -->
            <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
    
            <!-- Scripts -->
            <!-- @vite(['resources/css/app.css', 'resources/js/app.js']) -->
            <!-- Styles -->
            <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    
            <!-- Scripts -->
            <script src="{{ asset('js/app.js') }}" defer></script>
            
        </head>
        <body>
            <div class="font-sans text-gray-900 antialiased">
                {{ $slot }}
            </div>
        </body>
    </html>

    ▼resources/views/layouts/guest.app.phpを編集

    <!DOCTYPE html>
    <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta name="csrf-token" content="{{ csrf_token() }}">
    
            <title>{{ config('app.name', 'Laravel') }}</title>
    
            <!-- Fonts -->
            <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
    
            <!-- Scripts -->
            <!-- @vite(['resources/css/app.css', 'resources/js/app.js']) -->
            <!-- Styles -->
            <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    
            <!-- Scripts -->
            <script src="{{ asset('js/app.js') }}" defer></script>
    
        </head>
        <body class="font-sans antialiased">
            <div class="min-h-screen bg-gray-100">
                @include('layouts.navigation')
    
                <!-- Page Heading -->
                <header class="bg-white shadow">
                    <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
                        {{ $header }}
                    </div>
                </header>
    
                <!-- Page Content -->
                <main>
                    {{ $slot }}
                </main>
            </div>
        </body>
    </html>
    

    php artisan serveで改めて表示を確認すると正しく表示されることを確認

    ▼commit

    PS C:\MAMP\htdocs\step01\umarche> git config --global core.autoCRLF false
    PS C:\MAMP\htdocs\step01\umarche> git add -A
    PS C:\MAMP\htdocs\step01\umarche> git commit -m "add Breeze"
    [sec02_larabelBreeze 991eeb2] add Breeze
     53 files changed, 35895 insertions(+), 5 deletions(-)
    
    PS C:\MAMP\htdocs\step01\umarche> git push origin sec02_laravelBreeze
    Enumerating objects: 99, done.
    Counting objects: 100% (99/99), done.
    Delta compression using up to 12 threads
    Compressing objects: 100% (72/72), done.
    Writing objects: 100% (78/78), 250.66 KiB | 2.02 MiB/s, done.
    Total 78 (delta 24), reused 0 (delta 0), pack-reused 0 (from 0)
    remote: Resolving deltas: 100% (24/24), completed with 10 local objects.
    remote:
    remote: Create a pull request for 'sec02_laravelBreeze' on GitHub by visiting:
    remote:      https://github.com/idatokiya/laravel_umarche2/pull/new/sec02_laravelBreeze
    remote:
    To github.com:idatokiya/laravel_umarche2.git
     * [new branch]      sec02_laravelBreeze -> sec02_laravelBreeze

    日本語化

    ▼新しいブランチを作成

    PS C:\MAMP\htdocs\step01\umarche> git switch -c sec02_japaneseLocalization
    Switched to a new branch 'sec02_japaneseLocalization'
    PS C:\MAMP\htdocs\step01\umarche> git branch
      main
      sec01_initialSetting
    * sec02_japaneseLocalization
      sec02_laravelBreeze

    ▼日本語化対応ファイルを作成(laravel_umarche/resources/langディレクトリ)

    • ja.json
    • ja/auth.php
    • ja/pagination.php
    • ja/passwords.php
    • ja/validation-inline.php
    • ja/validation.php

    参考:https://github.com/idatokiya/laravel_umarche2/tree/sec02_japaneseLocalization

    ▼commit

    PS C:\MAMP\htdocs\step01\umarche> git config --global core.autoCRLF false
    PS C:\MAMP\htdocs\step01\umarche> git add -A
    PS C:\MAMP\htdocs\step01\umarche> git commit -m "日本語化対応"
    [sec02_japaneseLocalization a867cfb] 譌・譛ャ隱槫喧蟇セ蠢
     7 files changed, 268 insertions(+)
     create mode 160000 laravel_umarche
     create mode 100644 resources/lang/ja.json
     create mode 100644 resources/lang/ja/auth.php
     create mode 100644 resources/lang/ja/pagination.php
     create mode 100644 resources/lang/ja/passwords.php
     create mode 100644 resources/lang/ja/validation-inline.php
     create mode 100644 resources/lang/ja/validation.php
    PS C:\MAMP\htdocs\step01\umarche> git push origin sec02_japaneseLocalization
    Enumerating objects: 14, done.
    Counting objects: 100% (14/14), done.
    Delta compression using up to 12 threads
    Compressing objects: 100% (11/11), done.
    Writing objects: 100% (11/11), 4.55 KiB | 1.52 MiB/s, done.
    Total 11 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
    remote: Resolving deltas: 100% (1/1), completed with 1 local object.
    remote: 
    remote: Create a pull request for 'sec02_japaneseLocalization' on GitHub by visiting:
    remote:      https://github.com/idatokiya/laravel_umarche2/pull/new/sec02_japaneseLocalization
    remote:
    To github.com:idatokiya/laravel_umarche2.git
     * [new branch]      sec02_japaneseLocalization -> sec02_japaneseLocalization

    Tailwindcss ver3

    php artisan serveだけだと反映されない(Laravel側の簡易サーバでフロント側:Node.jsは見れない)

    npm run devnpm run watchで反映

    npm run watch
    随時、コンパイル

    ターミナル1: npm run watch
    ターミナル2: php artisan serve
    ターミナル3: Laravel各コマンド実行

    21. 準備 (ルート->コントローラ->ビュー)

    https://logsuke.com/web/programming/laravel/laravel-breeze-lang-ja

    Laravelをさくらインターネットで使用する方法

    SSH を利用

    TeraTermをダウンロード

    SSHプロトコルでサーバーを遠隔操作できるターミナルエミュレータで、Windows対応のフリーソフトです。

    ▼接続設定

    • ホスト:初期ドメイン(xxxxxx.sakura.ne.jp)…さくらインターネットコントロールパネルで確認できます
    • ユーザ名:アカウント …さくらインターネットコントロールパネルで確認できます
    • パスフレーズ:さくらインターネットコントロールパネルログインパスワード

    Welcome to FreeBSD!の表示で接続の確認ができます

    ▼終了方法について
    Tera Term のデフォルトでは、ログイン先サーバからログアウトしたり、ネットワークエラー等で接続が切れたりすると、同時に終了されます。

    https://qiita.com/risuracer/items/b6e6ccb95281d97089b2
    tailwindcss使い方

    tailwindcssメリット、デメリット

    メリット

    • class名を付与する必要がない

    デメリット

    • 事前にビルドの設定が必要

    導入方法

    npm(Node Package Manager)経由でインストール

    参考:https://logical-studio.com/develop/frontend/20220401-tailwindcss/#Tailwind_CSS_v3

    ・プロジェクトフォルダにて(tailwindcss_testフォルダ)

    初期化実施

    npm init -y

    ▼tailwindcss-test/package.jsonが作成されます

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

    Tailwind CSSをPostCSSプラグインとして導入するため、tailwind CSSに加えPostCSSもインストール

    ビルド時にpostcssコマンドを使うため、postcss-cliをインストール

    npm install -D tailwindcss postcss-cli autoprefixer

    Tailwind CSSとPostCSSのコンフィグファイルを生成

    npx tailwindcss init -p

    必要なディレクトリを作成

    • tailwindcss_test
      • dist
        • output.css
      • src
        • index.html
        • input.css

    ユーティリティクラスを使うファイルのパスを指定

    tailwind.config.jsを編集

    module.exports = {
      content: ["./src/**/*.{html,js}"],
      theme: {
        extend: {},
      },
      plugins: [],
    }

    ディレクティブの情報をinput.cssに入力

    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    ビルドコマンドの設定

    {
      "name": "tailwindcss_test",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "postcss ./src/input.css -o ./dist/output.css --watch --verbose"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "autoprefixer": "^10.4.17",
        "postcss-cli": "^11.0.0",
        "tailwindcss": "^3.4.1"
      }
    }
    

    npm run devコマンドを実行

    →output.cssにTailwind CSSの雛形が生成

    watchコマンドが走っているため、ユーティリティクラスを追加すると自動でそのCSSが生成されます

    実際にindex.htmlを編集して試してみます

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link href="../dist/output.css" rel="stylesheet" />
      </head>
      <body>
        <h1 class="text-3xl font-bold underline text-blue-600">Hello world!</h1>
      </body>
    </html>
    

    →正しくoutput.cssに追記されます

    .text-3xl {
      font-size: 1.875rem;
      line-height: 2.25rem;
    }
    .font-bold {
      font-weight: 700;
    }
    .text-blue-600 {
      --tw-text-opacity: 1;
      color: rgb(37 99 235 / var(--tw-text-opacity));
    }
    .underline {
      text-decoration-line: underline;
    }

    WordPressとTailwind CSS

    https://note.com/zoetaka38/n/n242b145d3741
    Laravelでtodoアプリ

    Laravel

    LaravelはPHPのフレームワークで有名です。

    2011年にリリースされた新しいフレームワークですが、世界中に普及しています。

    ECサイトや予約システム使用されることが多いです。

    MVC

    Model View Controllerパーツに分割して実装していくモデルです。

    • Model
      • データの処理、DBとのやりとりを行う
    • View
      • ユーザーに画面を表示
      • ユーザからの入力を受け付ける
    • Controller
      • ユーザからの入力をModelに依頼
      • Modelが処理したデータをViewに表示を依頼

    使われているフレームワーク

    PHP:Laravel、CakePHP、CodeIgniter、ZendFramework

    JavaScript:Backbone.js、Spine.js、JavaScriptMVC

    Laravel 利用方法 2024/02/24

    https://b-risk.jp/blog/2022/08/laravel/の記事の流れで実施

    • Windows
    • MAMPダウンロード済み
    https://b-risk.jp/blog/2022/08/laravel/

    Composerをインストール(Windows)

    https://weblabo.oscasierra.net/php-composer-windows-install/を参考

    Windows PowerShellでインストールを確認 ※一度開きなおす

    composer -V
    https://weblabo.oscasierra.net/php-composer-windows-install/

    Composerをインストール(Mac)

    下記記事を参考 ※homebrewでComposerをインストール

    https://god48.com/composer-install

    Laravelをインストール

    laravel_testディレクトリを作成

    laravel_testに移動

    composer create-project --prefer-dist laravel/laravel . "9.*"

    エラー発生

    php.iniファイルの編集が必要みたいです

    php.iniのパス

    php --ini

    参考 【PHP/Linux】php.ini の探し方と修正方法:https://developer.same-san.com/detail/php-ini

    php.iniのパスをみてみるとphp.iniはなく下記のベースファイル2種があります

    • php.ini-production
    • php.ini-development

    php.iniを編集

    2ヵ所:を削除

    extension=curl
    ;extension=ffi
    ;extension=ftp
    extension=fileinfo
    ;extension=gd
    ;extension=gettext
    ;extension=gmp

    始め上記のコメントアウトのみ実施したら、再度エラー

    エラー内容から検索した記事を参考に別の箇所をコメントアウト

    Laravelインストール時に出たzipのエラー解決備忘録:https://qiita.com/nejimawaso/items/55512b40b724e35880c3

    ;extension=soap
    ;extension=sockets
    ;extension=sodium
    ;extension=sqlite3
    ;extension=tidy
    ;extension=xsl
    extension=zip
    
    ;zend_extension=opcache

    再度Laravelインストールのためのコマンドを入力

    composer create-project --prefer-dist laravel/laravel . "9.*"

    ↓無事インストール完了

    Laravelの簡易サーバを立ち上げ

    php artisan serve

    「http://127.0.0.1:8000/」にアクセスすると画面が表示されます。

    Laravelの初期設定

    laravel_test/config/app.php

    
    'timezone' => 'Asia/Tokyo',
    
    
    'locale' => 'ja',
    
    'fallback_locale' => 'ja',
    
    'faker_locale' => 'ja_JP',
    

    laravel_test/.env
    (主に定数を設定しているファイル)

    
    APP_NAME=Laravel_Test
    

    laravel_test/.resources/views/welcome.blade.php

            <!-- <title>Laravel</title> -->
            <title>{{ config('app.name') }}</title>
    

    タイトルがLaravelからLaravel_Testに変更されます

    データベース接続情報の設定

    MAMPでデータベースの作成

    1. MAMP で「Open WebStart page」クリック
    2. ブラウザに表示されたhttp://localhost:8888/MAMP/のメニューの「TOOLS」の「PHPMYADMIN
    3. New」をクリック
    4. DB作成画面でデータベース名は「laravel_test」、照合順序は「utf8_general_ci」にして、「Create

    データベースの情報を「.env」で変更

    
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel_test
    DB_USERNAME=root
    DB_PASSWORD=root
    

    config/database.php」を編集

    デフォルトでも問題ない

            'mysql' => [
                'driver' => 'mysql',
                'url' => env('DATABASE_URL'),
                'host' => env('DB_HOST', '127.0.0.1'),
                'port' => env('DB_PORT', '3306'),
                'database' => env('DB_DATABASE', 'forge'),
                'username' => env('DB_USERNAME', 'forge'),
                'password' => env('DB_PASSWORD', ''),
                'unix_socket' => env('DB_SOCKET', ''),
                'charset' => 'utf8',
                'collation' => 'utf8_general_ci',
                'prefix' => '',
                'prefix_indexes' => true,
                'strict' => true,
                'engine' => null,
                'options' => extension_loaded('pdo_mysql') ? array_filter([
                    PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
                ]) : [],
            ],

    変更を反映

    ※php artisan serveを実行している状態であれば、「Ctrl + C」で停止

    php artisan config:clear

    反映後DB接続を確認するため

    php artisan migrateコマンドで確認するとエラー発生

    Illuminate\Database\QueryException

    エラー解決のためphp.iniを変更

    ;extension=pdo_firebird
    extension=pdo_mysql
    ;extension=pdo_oci

    Illuminate\Database\QueryException
    再度同エラー発生

    エラー内容のSQLSTATE[HY000] [2002] php_network_getaddresses: を調べたところデータベース接続ができていない

    .envファイルを開きデータベース情報を修正する必要があるとのこと

    改めてMySQLに接続してデータベース情報を確認
    →http://localhost:8888/MAMP/?language=Japanese

    上記を参考に.envを再度編集

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=8889
    DB_DATABASE=laravel_test
    DB_USERNAME=root
    DB_PASSWORD=root

    php artisan config:clear php artisan migrate

    ▼コマンドを実行すると下記の通りで正しく接続できたようです

    PS C:\Users\xxxx\laravel_test> php artisan migrate     
    
       INFO  Preparing database.
    
      Creating migration table ....................................................................................... 94ms DONE
    
       INFO  Running migrations.  
    
      2014_10_12_000000_create_users_table .......................................................................... 135ms DONE
      2014_10_12_100000_create_password_resets_table ................................................................ 161ms DONE
      2019_08_19_000000_create_failed_jobs_table .................................................................... 142ms DONE
      2019_12_14_000001_create_personal_access_tokens_table ......................................................... 187ms DONE
    
    PS C:\Users\xxxx\laravel_test> 

    ▼phpMyAdminにて更新すると下記の通り反映できてました(コピペで見づらいです、、)

    Containing the word: 
    Table Ascending	Action	Rows 	Type	Collation	Size	Overhead
    	failed_jobs	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
    	migrations	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	4	InnoDB	utf8_general_ci	16.0 KiB	-
    	password_resets	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
    	personal_access_tokens	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
    	users	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
    5 tables	Sum	4	InnoDB	utf8_general_ci	80.0 KiB	0 B

    基本的なLaravelのMVC

    モデルを作成する

    「todo_lists」というテーブルを作成

    モデルマイグレーションファイルコントローラーを同時に作成

    php artisan make:model TodoList -mc

    下記の通り3つのファイルを作成されます

       INFO  Model [C:\Users\xxxxxx\laravel_test\app/Models/TodoList.php] created successfully.
    
       INFO  Migration [C:\Users\xxxxxx\laravel_test\database\migrations/2024_02_27_120807_create_todo_lists_table.php] created successfully.
    
       INFO  Controller [C:\Users\xxxxxx\laravel_test\app/Http/Controllers/TodoListController.php] created successfully.
    database\migrationsフォルダ内に作成された「日付_create_todo_lists_table.php」を編集
        public function up()
        {
            Schema::create('todo_lists', function (Blueprint $table) {
                $table->id();
                $table->string('name', 100); //追記
                $table->timestamps();
            });
        }

    php artisan migrateコマンドを実行

    phpMyAdminにて「todo_lists」というテーブルが作成

    ダミーデータを登録

    シーダー

    php artisan make:seeder TodoListSeederコードを実行

    database\seedersにTodoListSeeder.phpが作成されます

    TodoListSeeder.phpを編集

    <?php
     
    namespace Database\Seeders;
     
    use Illuminate\Database\Console\Seeds\WithoutModelEvents;
    use Illuminate\Database\Seeder;
    use Illuminate\Support\Facades\DB; //追記
     
    class TodoListSeeder extends Seeder
    {
      /**
       * Run the database seeds.
       *
       * @return void
       */
      public function run()
      {
        DB::table('todo_lists')->insert(
          [
            [
              'name' => 'テスト1',
              'created_at' => now(),
              'updated_at' => now(),
            ],
            [
              'name' => 'テスト2',
              'created_at' => now(),
              'updated_at' => now(),
            ],
            [
              'name' => 'テスト3',
              'created_at' => now(),
              'updated_at' => now(),
            ],
          ]
        );
      }
    }
    

    database\seeders\DatabaseSeeder.phpを編集

    public function run()
    {
      $this->call([
        TodoListSeeder::class
      ]);
    }

    php artisan db:seed --class=TodoListSeeder

    ダミーデータが作成されます

    コントローラーを作成

    app\Http\Controllersフォルダ内のTodoListController.phpを編集

    編集内容:ModelクラスのTodolistからデータを取得→取得した値をViewに渡す処理

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Models\TodoList;//追記
    
    class TodoListController extends Controller
    {
      public function index(Request $request)
      {
        $todo_lists = TodoList::all();
    
        return view('todo_list.index', ['todo_lists' => $todo_lists]);
      }
    }
    

    参考:https://rocomadejapan.com/?cat=30

    ビューファイルを作成

    resources\views\todo_list\index.blade.phpという構成で作成

    <!DOCTYPE html>
    <html lang="ja">
     
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>テスト</title>
    </head>
     
    <body>
     
        @if ($todo_lists->isNotEmpty())
            <ul>
                @foreach ($todo_lists as $item)
                    <li>
                        {{ $item->name }}
                    </li>
                @endforeach
            </ul>
        @endif
     
    </body>
     
    </html>

    ルーティングを設定

    routes\web.phpに追記

    <?php
    
    use Illuminate\Support\Facades\Route;
    
    use App\Models\TodoList;//追記
    use App\Http\Controllers\TodoListController;//追記
    
    /*
    |--------------------------------------------------------------------------
    | Web Routes
    |--------------------------------------------------------------------------
    |
    | Here is where you can register web routes for your application. These
    | routes are loaded by the RouteServiceProvider within a group which
    | contains the "web" middleware group. Now create something great!
    |
    */
    
    Route::get('/', function () {
        return view('welcome');
    });
    
    Route::get('/list', [TodoListController::class, 'index']);

    php artisan serveを実行しhttp://127.0.0.1:8000/listにアクセスすると正しく表示されます

    TailwindCSSを導入

    先ほどのセクションの続きでTailwindCSSを導入します

    https://ntorelabo.com/?p=9933

    laravelディレクトリでnpm install -D tailwindcss postcss autoprefixerを実行

    続いてnpx tailwindcss init -p実行

    tailwind.config.jspostcss.config.js作成

    ▼tailwind.config.jsを編集

    /** @type {import('tailwindcss').Config} */
    module.exports = {
        content: [
            "./resources/**/*.blade.php",
            "./resources/**/*.js",
            "./resources/**/*.vue",
        ],
        theme: {
            extend: {},
        },
        plugins: [],
    }

    ▼resources\css\app.cssを編集

    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    参考サイトにはnpm run devを実行とありますが、php artisan serveコマンドも起動していないとページが表示できません

    中断してphp artisan serveを実行してサイト表示させるとVite manifest not found atというエラー

    npm run buildコマンドを実行する

    参考:https://rocomadejapan.com/?p=1035

    npm run devを実行していない時には、Vite側で、manifest.jsonファイルの情報を元に、public/build/assetsのファイルを参照してくれます。

    php artisan serveでサイトが正しく表示されます

    Todoアプリ実装

    tasksテーブル作成

    php artisan make:migration create_tasks_table

    →database/migrations/日付_create_tasks_table.phpが作成されます

    ▼日付_create_tasks_table.php

    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    return new class extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('tasks', function (Blueprint $table) {
                $table->id();
                $table->string('name', 100);
                $table->boolean('status')->default(false);
                $table->timestamp('updated_at')->useCurrent()->nullable();
                $table->timestamp('created_at')->useCurrent()->nullable();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('tasks');
        }
    };
    

    php artisan migrate実行するとphpMyAdminにてtasksテーブルが正しく作成されているのが確認できます

    Taskモデルを作成

    php artisan make:model Task

    →app\Models\Task.phpが作成されます

    コントローラーを作成

    php artisan make:controller TaskController --resource

    →app\Http\Controllers\TaskController.phpが作成されます

    ルート情報を追記

    ▼routes/web.php

    use App\Http\Controllers\TaskController;
    
    Route::resource('tasks', TaskController::class);

    php artisan route:listメソッドを確認

      GET|HEAD        / ........................................................................................................................................... 
      POST            _ignition/execute-solution .................................... ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
      GET|HEAD        _ignition/health-check ................................................ ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
      POST            _ignition/update-config ............................................. ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
      GET|HEAD        api/user .................................................................................................................................... 
      GET|HEAD        list ............................................................................................................... TodoListController@index
      GET|HEAD        sanctum/csrf-cookie ....................................................... sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
      GET|HEAD        tasks .................................................................................................... tasks.index › TaskController@index
      POST            tasks .................................................................................................... tasks.store › TaskController@store
      GET|HEAD        tasks/create ........................................................................................... tasks.create › TaskController@create
      GET|HEAD        tasks/{task} ............................................................................................... tasks.show › TaskController@show
      PUT|PATCH       tasks/{task} ........................................................................................... tasks.update › TaskController@update
      DELETE          tasks/{task} ......................................................................................... tasks.destroy › TaskController@destroy
      GET|HEAD        tasks/{task}/edit .......................................................................................... tasks.edit › TaskController@edit
    
                                                                                                                                                Showing [14] routes

    ビューを作成を作成

    ▼resources/views/tasks/index.blade.phpを作成

    <!DOCTYPE html>
    <html lang="ja">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Todo</title>
    
        @vite('resources/css/app.css')
    </head>
    
    <body class="flex flex-col min-h-[100vh]">
        <header class="bg-slate-800">
            <div class="max-w-7xl mx-auto px-4 sm:px-6">
                <div class="py-6">
                    <p class="text-white text-xl">Todoアプリ</p>
                </div>
            </div>
        </header>
    
        <main class="grow">
            <div class="max-w-7xl mx-auto px-4 sm:px-6">
                <div class="py-[100px]">
                    <p class="text-2xl font-bold text-center">今日は何する?</p>
                    <form action="/tasks" method="post" class="mt-10">
                      @csrf
    
                      <div class="flex flex-col items-center">
                        <label class="w-full max-w-3xl mx-auto">
                            <input
                                class="placeholder:italic placeholder:text-slate-400 block bg-white w-full border border-slate-300 rounded-md py-4 pl-4 shadow-sm focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm"
                                placeholder="洗濯物をする..." type="text" name="task_name" />
                        </label>
    
                        <button type="submit" class="mt-8 p-4 bg-slate-800 text-white w-full max-w-xs hover:bg-slate-900 transition-colors">
                            追加する
                        </button>
                      </div>
    
                    </form>
                </div>
            </div>
        </main>
        <footer class="bg-slate-800">
          <div class="max-w-7xl mx-auto px-4 sm:px-6">
            <div class="py-4 text-center">
                <p class="text-white text-sm">Todoアプリ</p>
            </div>
        </div>
        </footer>
    </body>
    
    </html>

    ▼TaskController.phpを編集

        public function index()
        {
            return view('tasks.index');
        }

    php artisan serveで確認したところTailwindCSSが読み込まれていない

    ▼参考:https://rocomadejapan.com/?p=1038

    一度サーバを停止しnpm run buildを実行し再度php artisan serveで確認すると正しく表示されました

    タスクを登録

    ▼TaskController.phpを編集

        public function store(Request $request)
        {
            $task_name = $request->input('task_name');
            dd($task_name);
        }

    テストですと入力してみるとテストです” // app/Http/Controllers/TaskController.php:38と表示されstoreメソッドに渡されているのが確認できます

    storeメソッド内で受け取った値をDBへ保存する設定

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Models\Task;//追加

    ▼TaskController.phpを編集

    public function store(Request $request)
    {
      //モデルをインスタンス化
      $task = new Task;
     
      //モデル->カラム名 = 値 で、データを割り当てる
      $task->name = $request->input('task_name');
     
      //データベースに保存
      $task->save();
     
      //リダイレクト
      return redirect('/tasks');
     
    }

    再度テストですと入力してみるとphpMyAdminを開いてtasksテーブルに登録されているのが確認きます

    バリデーション

    Validatorクラスを利用

    ▼TaskController.phpに以下を追記

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Models\Task;//追加
    use Illuminate\Support\Facades\Validator;//追加
    
    class TaskController extends Controller
    {
       …省略…
    
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            $rules = [
                'task_name' => 'required|max:100',
            ];
            
            $messages = ['required' => '必須項目です', 'max' => '100文字以下にしてください。'];
            
            Validator::make($request->all(), $rules, $messages)->validate();
    
            //モデルをインスタンス化
            $task = new Task;
    
            //モデル->カラム名 = 値 で、データを割り当てる
            $task->name = $request->input('task_name');
    
            //データベースに保存
            $task->save();
    
            //リダイレクト
            return redirect('/tasks');
        }
    
       …省略…

    ▼resources\views\todo_list\index.blade.phpに追記
    ※labelの中にあるinputタグの下

    @error('task_name')
      <div class="mt-3">
          <p class="text-red-500">
              {{ $message }}
          </p>
      </div>
    @enderror

    入力画面にて以下の通り正しく表示確認できます。
    ・何も記入しないで追加→「必須項目です」の表示
    ・100文字以上で入力「100文字以下にしてください。」の表示

    タスクを表示

    ▼TaskController.phpに以下を追記

        public function index()
        {
            $tasks = Task::all();
            
            return view('tasks.index', compact('tasks'));
        }
    

    ▼resources\views\todo_list\index.blade.phpに追記

    {{-- 追記 --}}
      @if ($tasks->isNotEmpty())
          <div class="max-w-7xl mx-auto mt-20">
              <div class="inline-block min-w-full py-2 align-middle">
                  <div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
                      <table class="min-w-full divide-y divide-gray-300">
                          <thead class="bg-gray-50">
                              <tr>
                                  <th scope="col"
                                      class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900">
                                      タスク</th>
                                  <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
                                      <span class="sr-only">Actions</span>
                                  </th>
                              </tr>
                          </thead>
                          <tbody class="divide-y divide-gray-200 bg-white">
                              @foreach ($tasks as $item)
                                  <tr>
                                      <td class="px-3 py-4 text-sm text-gray-500">
                                          <div>
                                              {{ $item->name }}
                                          </div>
                                      </td>
                                      <td class="p-0 text-right text-sm font-medium">
                                          <div class="flex justify-end">
                                              <div>
                                                  <form action="/tasks/{{ $item->id }}"
                                                      method="post"
                                                      class="inline-block text-gray-500 font-medium"
                                                      role="menuitem" tabindex="-1">
                                                      @csrf
                                                      @method('PUT')
                                                      <button type="submit"
                                                          class="bg-emerald-700 py-4 w-20 text-white md:hover:bg-emerald-800 transition-colors">完了</button>
                                                  </form>
                                              </div>
                                              <div>
                                                  <a href="/tasks/{{ $item->id }}/edit/"
                                                      class="inline-block text-center py-4 w-20 underline underline-offset-2 text-sky-600 md:hover:bg-sky-100 transition-colors">編集</a>
                                              </div>
                                              <div>
                                                  <form action="/tasks/{{ $item->id }}" method="post"
                                                      class="inline-block text-gray-500 font-medium"
                                                      role="menuitem" tabindex="-1">
                                                      @csrf
                                                      @method('DELETE')
                                                      <button type="submit"
                                                          class="py-4 w-20 md:hover:bg-slate-200 transition-colors">削除</button>
                                                  </form>
                                              </div>
                                          </div>
                                      </td>
                                  </tr>
                              @endforeach
                          </tbody>
                      </table>
                  </div>
              </div>
          </div>
      @endif
      {{-- 追記ここまで --}}

    ※先ほど同様一度サーバを停止しnpm run buildを実行し再度php artisan serveでスタイルが効きます

    タスクを編集

    ▼TaskController.phpに以下を追記

        public function edit($id)
        {
            $task = Task::find($id);
            return view('tasks.edit', compact('task'));
        }

    ▼resources/views/tasks/edit.blade.phpを作成

      <!DOCTYPE html>
      <html lang="ja">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <title>Todo</title>
      
          @vite('resources/css/app.css')
      </head>
      
      <body class="flex flex-col min-h-[100vh]">
          <header class="bg-slate-800">
              <div class="max-w-7xl mx-auto px-4 sm:px-6">
                  <div class="py-6">
                      <p class="text-white text-xl">Todoアプリ-編集画面</p>
                  </div>
              </div>
          </header>
      
          <main class="grow grid place-items-center">
              <div class="w-full mx-auto px-4 sm:px-6">
                  <div class="py-[100px]">
                      <form action="/tasks/{{ $task->id }}" method="post" class="mt-10">
                          @csrf
                          @method('PUT')
      
                          <div class="flex flex-col items-center">
                              <label class="w-full max-w-3xl mx-auto">
                                  <input
                                      class="placeholder:italic placeholder:text-slate-400 block bg-white w-full border border-slate-300 rounded-md py-4 pl-4 shadow-sm focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm"
                                      type="text" name="task_name" value="{{ $task->name }}" />
                                  @error('task_name')
                                      <div class="mt-3">
                                          <p class="text-red-500">
                                              {{ $message }}
                                          </p>
                                      </div>
                                  @enderror
                              </label>
      
                              <div class="mt-8 w-full flex items-center justify-center gap-10">
                                  <a href="/tasks" class="block shrink-0 underline underline-offset-2">
                                      戻る
                                  </a>
                                  <button type="submit"
                                      class="p-4 bg-sky-800 text-white w-full max-w-xs hover:bg-sky-900 transition-colors">
                                      編集する
                                  </button>
                              </div>
                          </div>
      
                      </form>
      
                  </div>
              </div>
          </main>
          <footer class="bg-slate-800">
              <div class="max-w-7xl mx-auto px-4 sm:px-6">
                  <div class="py-4 text-center">
                      <p class="text-white text-sm">Todoアプリ</p>
                  </div>
              </div>
          </footer>
      </body>
      
      </html>

    ▼TaskController.phpに以下を追記

        public function update(Request $request, $id)
        {
            $rules = [
                'task_name' => 'required|max:100',
              ];
            
              $messages = ['required' => '必須項目です', 'max' => '100文字以下にしてください。'];
            
              Validator::make($request->all(), $rules, $messages)->validate();
            
            
              //該当のタスクを検索
              $task = Task::find($id);
            
              //モデル->カラム名 = 値 で、データを割り当てる
              $task->name = $request->input('task_name');
            
              //データベースに保存
              $task->save();
            
              //リダイレクト
              return redirect('/tasks');
        }

    タスクを完了

    ▼resources\views\todo_list\index.blade.phpに追記

    <form action="/tasks/{{ $item->id }}"
        method="post"
        class="inline-block text-gray-500 font-medium"
        role="menuitem" tabindex="-1">
        @csrf
        @method('PUT')
     
        {{-- 追記 --}}
        <input type="hidden" name="status" value="{{$item->status}}">
        {{-- 追記 --}}
     
        <button type="submit"
            class="bg-emerald-700 py-4 w-20 text-white md:hover:bg-emerald-800 transition-colors">完了</button>
    </form>

    ▼TaskController.phpに以下を追記

      public function update(Request $request, $id)
      {
      
        dd($request->status);//追記

    デバッグとして完了ボタンを押すと、下記の通り0が取得でき、
    編集画面で編集するボタンを押すとnullが取得でき成功が確認

    デバッグでstatusの値の取得が確認できたので、
    ▼TaskController.phpを編集

      public function update(Request $request, $id)
      {
      
        //「編集する」ボタンをおしたとき
        if ($request->status === null) {
          $rules = [
            'task_name' => 'required|max:100',
          ];
      
          $messages = ['required' => '必須項目です', 'max' => '100文字以下にしてください。'];
      
          Validator::make($request->all(), $rules, $messages)->validate();
      
      
          //該当のタスクを検索
          $task = Task::find($id);
      
          //モデル->カラム名 = 値 で、データを割り当てる
          $task->name = $request->input('task_name');
      
          //データベースに保存
          $task->save();
        } else {
          //「完了」ボタンを押したとき
      
          //該当のタスクを検索
          $task = Task::find($id);
      
          //モデル->カラム名 = 値 で、データを割り当てる
          $task->status = true; //true:完了、false:未完了
      
          //データベースに保存
          $task->save();
        }
      
      
        //リダイレクト
        return redirect('/tasks');
      }

    完了するボタンを押すとphpmyadminにてstatusが1に変更されているのが確認できます

    一覧表示で未完了だけ表示

    ▼TaskController.phpを編集

    public function index()
    {
      $tasks = Task::where('status', false)->get();
     
      return view('tasks.index', compact('tasks'));
    }

    タスクを削除

    <div>
      <form onsubmit="return deleteTask();"
          action="/tasks/{{ $item->id }}" method="post"
          class="inline-block text-gray-500 font-medium"
          role="menuitem" tabindex="-1">
          @csrf
          @method('DELETE')
          <button type="submit"
              class="py-4 w-20 md:hover:bg-slate-200 transition-colors">削除</button>
      </form>
    </div>
    
       …省略…
    
       <script>
        function deleteTask() {
            if (confirm('本当に削除しますか?')) {
                return true;
            } else {
                return false;
            }
        }
      </script>
    </body>

    ▼TaskController.phpを編集

      public function destroy($id)
      {
        Task::find($id)->delete();
      
        return redirect('/tasks');
      }
    PostmanでPOSTリクエストをテストする方法

    Postmanのインストール

    自分の使用しているOS(Windows、Mac、またはLinux)を選び、「Download」ボタンをクリックします。

    https://www.postman.com/downloads/

    インストーラーを実行

    アカウントを作成せずに使用する場合は「Skip and go to the app」をクリック

    参考サイト

    https://qiita.com/ponsuke0531/items/03483449ea0df505a540
    AWS認定ソリューションアーキテクト-アソシエイトレベル

    AWSとは

    AWSとは近年流行しているクラウド化で利用されているサービスです。

    AWSの資格の種類

    AWS認定試験は2023/8月時点で12種類に資格があります。

    • AWS認定Solutions Architect(ソリューションアーキテクト)アソシエイト(SAA-C02)
      システム設計
    • AWS認定Developer(デベロッパー)アソシエイト(DVA-C01)
      開発
    • AWS認定SysOps Administrator(シスオプス アドミニストレーター)アソシエイト(SOA‐C02)
      管理運用
    (設計者向け)
    ソリューションアーキテクト
    (開発者向け)
    デベロッパー
    (運用管理者向け)
    Sys Ops アドミニストレーター
    Professional LevelAWS認定
    ソリューションアーキテクト
    -プロフェッショナルレベル試験
    AWS認定
    Dev Ops エンジニア
    -プロフェッショナルレベル試験
    Associate LevelAWS認定
    ソリューションアーキテクト
    -アソシエイトレベル試験
    AWS認定
    デベロッパー
    -アソシエイトレベル試験
    AWS認定
    Sys Ops アドミニストレーター
    -アソシエイトレベル試験
    Foundation LevelAWS認定
    クラウドプラクティナー試験

    インフラエンジニアとしてどのようなことがしたいか、明確にあるほうが、 案件をアサインしやすい 例)AWSの環境構築をしたいので、キャリアは未経験ですが、AWSの資格をアソシエイトを3つプロを一つ取得しました。

    AWS認定ソリューションアーキテクト-アソシエイトレベル試験概要

    セキュアなアーキテクチャの設計30%
    弾力性に優れたアーキテクチャの設計26%
    高パフォーマンスなアーキテクチャの設計24%
    コストを最適化したアーキテクチャの設計20%
    • 試験時間:130分
    • 問題数:65問
    • 合格ライン:720点/1000点

    重要サービス
    EC2 S3 VPC IAM ELB/Auto Scaling

    IAM(AWS Identity and Access Management)
    IAM は、AWS リソースへのアクセス権限を管理するためのサービスです。IAM より、AWS アカウントで誰が何(認証・認可)を実行できるかを定義します。

    Permissions Boundary(アクセス許可境界)
    IAMユーザーやIAMロールの操作可能範囲を限定、制約を設ける機能

    リソースの記述はARN(Amazon Resource Name)形式
    arn:aws:サービス:リージョン:アカウントID:リソース

    VPC(Amazon Virtual Private Cloud)
    仮想ネットワーク

    ↓1つのVPCはリージョン内すべてのAZにまたがる

    VPCエンドポイント
    インターネットとの通信が制限されているプライベートサブネット内のAWSリソースから、インターネットゲートウェイを経由せずにVPC外のAWSサービスへアクセス可能にする機能

    EC2(Elastic Compute Cloud

    elastic … 拡張性
    AWS上に仮想サーバを作るサービス

    EC2を起動するとき元となるイメージをAMI(Amazon Machine Image)を選んで作成します。
    …AMI(Amazon マシンイメージ)は、EC2インスタンスを起動するために必要なOSミドルウェアなどのテンプレートです。

    従量課金型(使った分だけ課金)
    ・起動中(Running)→費用発生
    ・停止中(Stopped)→EBSの費用のみ発生
    ・削除済み(Terminated)→発生しない

    ELB(Elastic Load Balancing)
    アプリケーションへの負荷やCPUの稼働状況をリアルタイムにモニタリングできるロードバランサーです

    RDS(Amazon Relational Database Service)
    データベースのマネージドサービス
    Aurora AWSが独自に開発

    S3(Amazon Simple Storage Service)
    ・オブジェクトストレージサービス … データを固有のIDを持つ「オブジェクト」として扱う→ディレクトリのような階層構造を持たない
    ・AWSのストレージサービスの中で1TBあたりの保存料金が最も安い
    ・保存容量が無制限

    ストレージクラス保存料金の高い順取出し料金取出し遅延保存AZ最短保存期間
    S3 Standard
    標準(Standard)
    1なしなし3以上なし
    S3 Intelligent-Tiering
    アクセス頻度が予測不能なデータを保存する際に適している
    変動なし変動3以上なし
    S3 Standard-IA
    (S3 Standard-Infrequent Access)
    2ありなし3以上30日
    S3 One Zone-IA3ありなし130日
    S3 Glacier Instant Retrieval
    ※アーカイブデータ向け
    4ありなし3以上90日
    S3 Glacier Flexible Retrieval
    ※アーカイブデータ向け
    5あり数分~数時間3以上90日
    S3 Glacier Deep Archive
    ※アーカイブデータ向け
    6あり数時間3以上180日

    バケット
    Amazon S3のオブジェクトが保存される領域
    ・一つのバケットにはオブジェクト数が無制限で保存可能
    ・バケット名はグローバルで一意、作成したバケット名は変更は不可

    マルチパートアップロード
    S3バケットに5GBを超えるファイルをアップロードするときに利用
    ※S3バケットに保存できるオブジェクトの最大サイズは5TBですが、一度にアップロードできる最大サイズは5GB

    クロスリージョンレプリケーション
    S3オブジェクトを自動的に異なるリージョンに保存したい場合に利用

    S3 Transfer Acceleration
    ユーザーからS3バケットへ最適化したネットワークルートを経由してデータを転送する機能

    ライフサイクル
     ・移行アクション … 利用頻度に応じてストレージクラスを変更
     ・有効期限アクション … 指定された期限を超えたオブジェクトを削除

    ライフサイクルポリシー
    S3バケット内のデータに対して、ストレージクラスの変更やオブジェクトの削除を自動化する機能

    著名付きURL
    アクセスを許可したいオブジェクトに対して期限を指定してURLを発行

    バケットポリシー
    ・S3で保存しているデータにバケット単位でアクセス権限を設定する機能
    ・サーバー側の暗号化(Server-Side Encryption:SSE)を強制できます

    <サーバー側の暗号化には、以下3種類の方法があります>

    1. Server-Side Encryption:SSE
      データをS3に保存する時にサーバーで暗号化する方法
    2. SSE-KMS
      AWS KMS(AWS Key Management Service)に保存されているKMSキーを使用する
    3. SSE-C
      ユーザーが管理している鍵を使用する

    バージョニング
    オブジェクトの世代管理ができる機能

    静的Webサイトホスティング
    バケットに保存している静的コンテンツ(HTMLやJPGなど)をWebサイトとして公開できる機能

    MFA Delete
    S3のバージョニング機能で世代管理されているオブジェクトを削除する際に、MFAデバイス認証が必要となる機能

    オブジェクトロック
    S3バケットに保存したオブジェクトに対して更新・削除を制限する機能
    ・S3バケット作成時にのみ設定可能
    ・オブジェクトロックを有効にするとバージョニング機能も有効になります。
    ※主にオブジェクトが意図的に改ざん・削除されることを防止する目的で使用

    • リテンションモード … 一定期間の保護
      • ガバナンスモード … s3:BypassGovernance Retention という権限がないと変更できない
      • コンプライアンスモード … 保護期間が明けるまで誰も上書き削除ができない
    • リーガルホールド … 保護期間を設定しない

    グローバルインフラストラクチャとネットワーク

    リージョン
    日本国内には「東京リージョン」と「大阪リージョン」の2つのリージョンが存在

    アベイラビリティゾーン(AZ)

    エッジロケーション
    ユーザに近いネットワークで高速なコンテンツを配信

    CIDRブロック
    VPCで作成者はIPアドレス(CIDRブロック)をアサインできます
    /16~/28の範囲

    ルートテーブル
    ルーティング設計
    ・サブネットに1つずつ設定

    インターネットゲートウェイ(IGW)
    VPCとインターネットを接続するためのゲートウェイ

    NATゲートウェイ
    ネットワークアドレス変換機能を持ちプライベートサブネットからインターネットへの通信を可能にする

    NATインスタンス
    ・NATゲートウェイと同じくプライベートサブネットからインターネットへの通信を可能にする
    ・EC2インスタンスから作成
    ・ポート転送機能を設定可能
    ・IPv4専用

    仮想プライベートゲートウェイ(VGW)
    ・VPCごとに1つだけ紐づけることが可能

    VPCエンドポイント
    インターネットとの通信が制限されているプライベートサブネット内のAWSリソースから、インターネットゲートウェイを経由せずにVPC外のAWSサービスへアクセス可能にする機能

    VPCピアリング
    2つのVPC間でプライベートな接続をするための機能
    ・異なるVPCアカウント間でも可能

    VPCフローログ

    AWS Direct Connectゲートウェイ
    オンプレミスと物理専用線で接続するサービス 
    ※インターネットを経由しないプライベートな接続を確保
    ・ZVPCと拠点を1対1で繋ぎます

    AWS Transit Gateway
    複数のVPC、Direct Connect、VPNをスター型トポロジーで接続
    ※ハブを介して、ネットワークを接続するクラウドルーター
    →ネットワークが簡素化

    AWS Site-to-Site VPN(サイト間VPN)
    カスタマーゲートウェイ(オンプレミスのルーター)とVPCの仮想プライベートゲートウェイ(VGW:Virtual Private Gateway)を、インターネットVPN(VPNトンネル)で接続するサービス

    コンピューティングと関連サービス
    Lambda/API Gateway ECS/Fargate/EKS

    EC2(Elastic Compute Cloud

    elastic … 拡張性
    AWS上に仮想サーバを作るサービス

    EC2を起動するとき元となるイメージをAMI(Amazon Machine Image)を選んで作成します。
    …AMI(Amazon マシンイメージ)は、EC2インスタンスを起動するために必要なOSミドルウェアなどのテンプレートです。

    従量課金型(使った分だけ課金)
    ・起動中(Running)→費用発生
    ・停止中(Stopped)→EBSの費用のみ発生
    ・削除済み(Terminated)→発生しない

    スポットインスタンス
    AWSが余らせているEC2リソースを入札形式で利用

    「スポットフリート」はスポットインスタンスのオプションの一つです。必要なインスタンス数を指定することで、指定した数のスポットインスタンスが起動します。スポットインスタンスが中断されて必要なインスタンス数を下回った場合、自動的にインスタンスを補充してインスタンス数を維持します。

    ハードウェア専有インスタンス(Dedicated Instances)は、他のAWSアカウントとは分離された専用ハードウェアでEC2インスタンスを利用できる購入オプションです。物理的なCPUソケット、コア数、ホストIDは確認できません。

    ・Dedicated Hosts(専有ホスト)
    他のEC2インスタンスとは分離された専用ハードウェアで利用できる購入オプションです。
    物理的なCPUソケット、コア数、ホストIDを確認する必要がない場合、ハードウェア専有インスタンスの方が低価格で利用できるので誤りです。

    リザーブドインスタンス(RI)
    長期間の利用を約束することで、割引を受ける

    ELB
    スケールアウト時の負荷分散を担うサービス
    CLB(Classic Load Balancer):L4/L7
    ALB(Application Load Balancer):L7 CLBより後に登場、機能豊富
    NLB(Network Load Balancer):L4 HTTP(S)以外のプロトコル通信時での負荷分散で利用

    ヘルスチェック(ELBの機能)
    インスタンスが正常に動作しているかチェック

    Auto Scaling
    EC2の状況に応じて自動的にインスタンスの数を増減させる機能

    ECS(Amazon Elastic Container Service)
    Docker環境を用意
    ・Task:EC2インスタンス上で実行されるコンテナ
    Cluster:Taskを保有しているEC2インスタンス
    Task Definition:Cluster上で動作するTaskの定義

    Lambda(ラムダ)
    サーバーをプロビジョニングしなくてもプロジェクトを実行できるコンピューティングサービス

    Lambda関数
    実行するプログラムとその実行トリガーとなるイベントを事前に定義する関数
    ・割り当てるメモリ用
    ・タイムアウトまでの時間
    ・Lambdaに割り当てるIAMロール
    ・VPC内外

    ストレージサービス
    S3 EBS EFS FSx Storage Gateway Snow Family

    EBS(Elastic Block Store)
    ブロックストレージ
    「Elastic」…用途に合わせて柔軟な使用ができる

    汎用SSD(gp3)3,000IOPS
    開発環境を構築する時に最適
    1GB〜16TB
    プロビジョンドIOPS(io2)64,000IOPS
    マルチアタッチ
    4GB〜16TB
    スループット最適化HDD(st1)500IOPS
    大量のデータ
    125GB〜16TB
    コールドHDD(sc1)250IOPS
    EBSの中で一番低コスト
    アクセス頻度の低いログデータやバックアップデータの保存
    125GB〜16TB

    EFSElastic File System
    Amazon EFSはNFS(Network File System)プロトコルをサポートするファイルストレージサービス

    ▼EFSのパフォーマンスモード

    汎用モードファイルサービスなど一般的な用途を想定したモードで、レイテンシーを優先する場合に使用するモードです。
    最大I/Oパフォーマンスモード・レイテンシーが汎用モードに比べ、わずかに長くなる
    ・合計スループットを優先する場合に使用

    ▼EFSのスループットモード

    バーストスループットモード・ベースラインとなるスループットが設定されている
    ・一時的なスループットの上昇にも耐えられるバースト機能を持っている
    プロビジョニングスループットモードバーストモードで許容されている以上の要件がある場合に使用
    エラスティックスループットモード・自動的にスケールアップダウン
    ・パフォーマンスもーどが汎用モード時のみ利用可

    FSx
    ファイルストレージサービス
    ・FSx for Windowsファイルサーバー
    ・FSx for Lustre
    ・FSx for NetApp ONTAP
    ・FSx for OpenZFS

    FSx for Windowsファイルサーバー
    Windows上にファイルシステムを提供
    SMBプロトコルを使用…主にWindowsコンピュータ間において、ファイル共有やプリンタ共有に使用されるプロトコル

    Storage Gateway
    オンプレミスにあるデータをクラウドに連携させるための受け口

    AWS Storage GatewayのS3ファイルゲートウェイは、オンプレミスからNFS(Network File System)またはSMB(Server Message Block)を使用してS3バケットへアクセスできるようにするゲートウェイタイプです。ローカル(オンプレミス)にキャッシュストレージを持つため低レイテンシでのアクセスも可能です。

    データベースサービス
    RDS/Aurora Redshift DynamoDB ElastiCache

    ▼AWSのデータサービス

    タイプサービス
    リレーショナル
    SQL
    Amazon Aurora、Amazon RDS、Amazon Redshift
    NoSQL キー値Amazon DynanoDB
    NoSQL インメモリAmazon ElastiCache、Amazon MemoryDB for Redis
    NoSQL ドキュメントAmazon DocumentDB
    NoSQL ワイドカラムAmazon Keyspaces
    NoSQL グラフAmazon Neptune
    時系列Amazon Timestream
    台帳AmazonQLDB

    Amazon RDS
    ・マルチAZ構成
    ・リードレプリカ

    Amazon Aurora
    ・DBクラスタ
    ・Auroraレプリカ

    データベースへの負荷に応じて動的にレプリカインスタンスを増減するAuto Scaling機能を備えています。

    Redshift
    ・データウェアハウス向け(データの「倉庫」
    ・拡張性
     →MPP…処理を複数のノードで分散(スケールアウト)
     →シェアードナッシング…各ノードがディスクを共有しない(I/O性能の劣化を回避)

    Redshift Spectrum
    Redshift内にデータを取り込むことなくクエリの実行が可能

    DynamoDB
    ・Key‐Value型
    ・NoSQL
    ・階層的なデータ構造をもったJSON形式のデータの扱いについてもサポート

    DynamoDBでは自動的に3つのAZにデータが保存されます

    DynamoDB Accelerator(DAX)
    DynamoDBの前段にキャッシュクラスタを構成→性能向上

    <Amazon DynamoDBには2つのバックアップ方法があります>
    オンデマンドバックアップ…ユーザーが任意のタイミングで作成するバックアップ
    ポイントインタイムリカバリ(PITR)…差分バックアップが定期的に自動で取得(35日前まで遡ることができます)

    DynamoDB Streams
    Amazon DynamoDBのDynamoDB Streams(ストリーム)とは、テーブルに対して行われた直近の24時間の変更(追加や更新、削除)をログに保存する機能です。

    ElastiCache
    ・インメモリ型データベース
    1)Memcached:再起動ですべてのデータが消える
    2)Redis:Memcachedよりも多くのデータ型が利用可能、データ永続性能

    マネジメント、ガバナンス
    CloudWatch CloudTrail Elastic Beanstalk CloudFormation Trusted Advisor AWS Systems Manager

    Amazon CloudWatch
    AWSサービスやオンプレミス(自社運用)のシステムを監視するサービス
    状態に応じたアクションを取らせることができます。

    メトリクスCloudWatchが監視する様々なリソースの情報は「メトリクス」と呼ばれます(インスタンスのCPU使用率やディスクの使用状況

    標準メトリクスCPU使用率、
    ディスク読み取り書き込み量、
    ネットワーク使用率
    カスタムメトリクスメモリ使用量、
    ディスク空き容量・使用状況、
    プロセス情報

    AWS CloudTrail
    AWSサービスに対して「いつ」「誰によって」「どのような操作が行われたのか」を記録・保存するサービスです
    ・管理イベント … ユーザーのログイン、EC2インスタンスの作成 など
    ・データイベント … S3上のオブジェクト(データ)の操作、Lambda関数の実行
    ・インサイトイベント … 通常と異なる操作(書き込みAPIの呼び出し)

    Amazon CloudWatch Logs
    Amazon CloudWatch LogsはAWSサービスやEC2インスタンスのOSやアプリケーションのログを収集し、一元管理するサービスです
    例)CloudTrailにおけるAWSサービスの操作ログや、VPCフローログ

    AWS CloudFormation
    AWSのリソースをコード化しプロビジョニング(構築)するサービスです。
    →IaC(Infrastructure as Code)

    AWS Elastic Beanstalkはアプリケーションが動作する定番の環境を自動で構築するサービスです。開発者は、用意された環境にアプリケーションをアップロードするだけでデプロイ(実行環境への展開)を行うことができます

    AWS Systems Manager Session Manager
    ・EC2インスタンスへマネジメントコンソールやAWS CLIからセキュアにログインできる機能
    ・プライベートサブネットにあるインスタンスへも踏み台サーバーなしで接続が可能

    セキュリティ、アイデンティティ、コンプライアンス
    WAF/Shield KMS/CloudHSM

    AWS Shield
    DDoS攻撃からの保護に特化したサービス

    AWS WAF(Web Application Firewall)
    脆弱性を突く攻撃(クロスサイトスクリプティングやSQLインジェクションなど)から、Webアプリケーションを保護するサービスです
    Web ACL地理的制限

    Network Load Balancer(NLB)とClassic Load Balancer(CLB)には対応していないので利用できません

    AWS Network Firewall
    ・VPC向けのファイアウォール機能
    ・侵入防止システム(IPS)やドメイン名によるトラフィックのフィルタリングなど、セキュリティグループやネットワークACLよりもさらに高度な機能
    ・VPC上のアウトバウンド及びインバウンド両方のトラフィックを検査可能
    ・特定のドメイン名を含むURLへのアクセスのみを許可したり、特定の送信元からのトラフィック以外は全てブロックするなど、きめ細かな通信の制御が可能

    ネットワーク、コンテンツ配信
    Route 53 CloudFront Global Accelerator Direct Connect/VPN

    CloudFront
    AWSが提供する高速でセキュアなコンテンツ配信ネットワークサービス
    ・「地理的制限」というクライアントからのアクセスを国別に制限できる機能があります

    フィールドレベル暗号化
    フィールドレベル暗号化は、ユーザーから送信されたHTMLフォームのPOSTリクエストのうち、一部のフィールドを暗号化し、特定のアプリケーションでのみ復号可能とするCloudFrontの機能です。

    アプリケーション統合
    SQS SNS

    SQS(Amazon Simple Queue Service)
    フルマネージドのメッセージキューイングサービスであり、サービス同士の橋渡しを担います。SQSはプル型なので、受信側の都合の良いタイミングでSQSへポーリング(問い合わせ)を行って、メッセージを受け取りま

    SNS(Amazon Simple Notification Service)
    プッシュ型のメッセージングサービス
    SNSはプッシュ型なので、サブクライバー(受信者)の状態に関わらずメッセージを配信します。
    トピックという単位で情報を管理

    分析
    Kinesis EMR Glue Athena

    AWS kinesisには大きく分けて3つの機能があります。

    • Amazon Kinesis Data Streams
    • Amazon Kinesis Data Firehose
    • Amazon Kinesis Data Analytics

    Kinesis Data Streams
    Kinesis Data Streamsはストリーミングデータを収集します。ストリーム上のデータは分析や機械学習などを行うアプリケーションがリアルタイムに読みだして処理します。

    Kinesis Data Firehose
    Kinesis Data FirehoseはストリーミングデータをAmazon S3やRedshiftなどへ配信するサービスです

    AWS Glue
    フルマネージドのサーバーレスETLサービス
    複数のデータソース(S3やDynamoDBなど)からデータを抽出し、変換・統合したデータをターゲット(Redshiftなど)へ格納
    ・クローラーはデータソースからデータの抽出を行い、データカタログを作成

    【チートシート】Linuc Lv1-102

    シェル及びスクリプト

    bash
    Bourne Again Shell

    環境設定ファイル

    ログイン時に実行される

    1)/etc/profile
    2)~/.bash_profile
    3)~/.bash_login
    4)~/.profile

    【全ユーザ】/etc/profileログイン時 1 1環境変数などaliasやfunction。
    【全ユーザ】/etc/bash.bashrcbash起動時 2環境変数を設定 alias
    Debian系
    【全ユーザ】/etc/bashrcbash起動時 5alias
    RedHat系
    【各ユーザ】~/.bash_profileログイン時 2 3環境変数など
    【各ユーザ】~/.bash_loginログイン時 3
    【各ユーザ】~/.profileログイン時 4
    【各ユーザ】~/.bashrcbash起動時 4aliasの設定
    【各ユーザ】~/.bash_logoutログアウト時ログアウト時実行させたい処理

    if [条件式]; then
    分岐処理1
    fi


    if [条件式1]; then
    分岐処理1
    elif [条件式2]; then
    分岐処理2
    else
    分岐処理3
    fi


    i=0
    while [ $i -ne 10 ]
    do
    echo $i
    i=i+1
    done


    for INT in 1 2 3
      in
       echo $INT
      done

    -dファイル名がディレクトリ名なら真
    -fファイルの場合は真
    -eファイルが存在するなら真
    -Lシンボリックリンクなら真
    -r読み取り可能なら真
    -w書き込み可能なら真
    -x実行可能なら真

    ネットワークの基礎

    /etc/hostname ファイル
    ホスト名が記述されている

    /etc/hosts ファイル
    ホスト名とIPアドレスの対応

    NetworkManager
    ネットワークを管理するサブシステム

    nmcli
    NetworkManagerではnmcliコマンドでネットワークの設定、接続の管理、状態の管理

    ip
    ネットワークインターフェイスやルーティングテーブル、ARPテーブルを管理

    ifconfig

    IPアドレスIPアドレスを設定する
    netmask サブネットマスクサブネットマスクを設定
    upネットワークインターフェースを有効化
    downネットワークインターフェースを無効化

    ifup ifdown
    ネットワークインターフェースの有効/無効化の操作

    ping

    traceroute

    tracepath tracepath6

    hostname [ホスト名]
    ホスト名を指定している場合ホスト名を変更、ホスト名を指定していない場合現在のホスト名を表示

    nmap
    ポートの状態

    netstat
    ネットワークに関する様々な情報を表示

    ss
    最近のディストリビューションではnetstatに代わって使用されている

    -n –numericサービス名の名前解決を行わない(ポート番号を表示)
    -r –resolve名前解決を行う
    「domain」の後ろには、通常はそのコンピュータが所属するドメインを指定します。
    このようにすると、名前解決の際にホスト名だけを入力したとき、
    domainの後ろに記述したドメイン名を付加して名前解決を行ってくれます。
    -e –extended詳細情報を表示
    -o –optionsタイマー情報も表示する
    -m –memory各ソケットのメモリの使用量も表示する
    -p –processesソケットを使用しているプロセスも表示する
    netstatソケット、インターフェイスごとのネットワーク統計など表示
    ss「ソケット」についての情報などを表示
    ※従来から移行 netstat → ss
    lsoflsofコマンドは、プロセスが開いているファイルを表示するコマンドですが、
    -iオプションを指定すると、開いているポートを確認できます。実行にはroot権限が必要です。
    nmap攻撃者がネットワーク経由で開いているポートを確認する行為をポートスキャンといいます。nmapコマンドでポートスキャンを行えます
    fuserポートを開いているプロセスを特定するには、fuserコマンドも使えます。

    nc(netcat)
    ネットワーク通信の確認

    ルーティングテーブルを表示
    route
    netstat -r
    ip route
    ip route show

    route
    ルーティングテーブルの表示、操作

    ifconfigコマンドインターフェースの状況を確認、設定
    ipコマンドOPTION [a(address 全てのIPアドレスを表示link route neigh ..]
    COMMAND [show add del]
    hostnameコマンドシステムのホスト名を確認したり、変更
    OPTION “-I(–all-ip-addresses)全てのIPアドレスを表示
    nmcliコマンドNetworkManagerを制御して、ネットワーク状況を確認、設定

    route ip route
    ▼追加
    route add default gw 172.17.0.1
    ip route add default via 172.17.0.1
    route add -net 192.168.0.0 gw 172.17.0.1 netmask 255.255.0.0 eth0
    ip route add 10.1.1.0/24 via 192.168.1.1

    ▼削除

    ip route delete default

    /etc/resolv.conf
    どこにあるDNSサーバを使用するか設定

    /etc/nsswitch.conf
    名前解決の手段の順序で使用するかを設定

    getentコマンド
    getentコマンドは、指定したデータベースからユーザーやグループの情報一覧を表示することができます。
    nsswitch.confの設定を確認するのに役立つ

    ドメイン→アドレス
    nslookup に代わる dig、host

    host
    ホストやドメインに関する情報を表示、デフォルトではホスト名とIPアドレスの変換をするコマンド

    dig
    digコマンドはDNSサーバに登録されている情報を詳しく表示
    digコマンド形式……dig @server domain query-type
    query-type例
    A: ネットワークアドレス (省略時)
    NS: ネームサーバ
    MX: メールサーバの情報
    SOAドメインのゾーン情報
    ANY: 知っているすべての情報
    TXT:テキスト情報

    システム管理

    重要なシステムサービス

    dateコマンド
    システム時刻を参照して現在の日時が表示されます。
    date [MMDDhhmm[[CC]YY][.ss]]
    「2020年3月4日10時」# date 030410002020

    date “+%Y%m%d”
    「年/月/日(曜日)」

    hwclockコマンド
    ハードウェア時刻の参照や設定を行います。設定にはroot権限が必要です。

    オプション
    -r –showハードウェア時刻を表示
    -w –systohcシステム時刻をハードウェア時刻に
    -s –hctosysハードウェア時刻をシステム時刻に

    timedatectlコマンド
    timedatectlコマンドで日付と時刻、タイムゾーンを管理できます。

    サブコマンド
    status現在の状態を表示(デフォルト)
    set-time 時刻時刻を設定
    set-time 日付日付を設定
    set-time 日付 時刻日付と時刻を設定
    set-timezone タイムゾーンタイムゾーンを設定
    list-timezonesタイムゾーン一覧を表示する
    set-ntp yes|noNTPを使うかどうか

    /usr/share/zoneinfoディレクトリ
    タイムゾーンの情報は、/usr/share/zoneinfoディレクトリ以下のバイナリファイルに格納

    ntpdateコマンド
    ntpdateコマンドを使うと、NTPサーバーから正確な時刻を取得できます。

    /etc/ntp.conf
    NTPサーバーの設定は/etc/ntp.confで行います。


    Chrony
    Chronyはntpd/ntpdateの代替となるNTPサーバー/クライアントソフトウェアです。デーモンプロセスchronydと、クライアントコマンドchronycから構成されます。

    chronyc [サブコマンド]
    chronydの管理はchronycコマンドで行います。

    syslog
    Linuxではsyslogを使って、さまざまなイベントをログファイルに記録したり、コンソールに表示したりできるようになっています。
    システムのログ(シスログ)を取得して処理するソフトウェアには、syslogのほか、rsyslogsyslog-ngなどが使われています。

    rsyslogの設定は、/etc/rsyslog.confファイルおよび/etc/rsyslog.dディレクトリ以下のファイルで行います。

    ファシリティ
    ログメッセージ生成元のプログラムは、メッセージにファシリティとプライオリティをタグ付けして出力します。ファシリティ(facility)はメッセージの生成元を表します。

    ファシリティ
    auth authpriv認証システム
    croncron
    deamon各種デーモン
    kernカーネル
    lpr印刷システム
    mailメールサービス
    userユーザーアプリケーションの出力
    local0~local7ローカルシステム

    loggerコマンド
    loggerコマンドを使ってログメッセージを生成することもできます。

    systemd-journaldデーモン
    systemdの動作するシステムではsystemd-journaldデーモンを動作させ、ログの一元管理を行います。systemd-journaldはsystemdから起動したプロセスの標準出力やsyslogへのログメッセージをバイナリ形式で記録します。

    /etc/systemd/journald.conf
    systemd-journaldの設定は/etc/systemd/journald.confで行います。

    systemd-catコマンド
    systemdを採用したシステムでは、systemd-catコマンドを使って、コマンドの実行結果をジャーナルに書き込むことができます。

    journalctlコマンド
    systemdを採用したシステムでは、journalctlコマンドを使ってsystemdのログ(ジャーナル)を閲覧できます。

    オプション
    -a –a省略せず表示
    -b –boot
    -f –follow新規に追加されたログをリアルタイムを表示
    -k –dmesgカーネルからのメッセージを表示
    -l –full全て表示
    -n –lines指定行数分表示
    (デフォルト10行)
    –no-pagerデフォルトで使われるlessコマンドを使用しない
    -o –output
    -r –reverse最古のログから表示(デフォルト)
    →最新のログから表示
    –since指定した日付時刻以降
    -u –unit特定のユニット
    –until指定した日付時刻まで表示

    logrotateコマンド
    logrotateコマンドを実行すると、ただちにログのローテーションを実施できます。-fオプションで設定ファイルを指定します。


    MTA
    電子メールを取り扱うソフトウェアには、MTA(Message Transfer Agent)やMDA(Mail Delivery Agent)、MUA(Mail User Agent)があります。

    mailqコマンド
    メールキューの内容を表示するには、mailqコマンドを使います。

    mailコマンド
    コマンドラインでメールを送信したり、受信メールを確認するには、mailコマンドを使います。

    /etc/aliasesファイル
    /etc/aliasesファイルを利用すると、メールアドレスの別名(エイリアス)を設定できます。
    この設定を有効にするには、newaliasesコマンドを使います。

    .forwardファイル
    各ユーザーのホームディレクトリに.forwardファイルを用意し、その中に転送先のメールアドレスを記述します。この方法は、一時的にメールを転送したい場合などに便利です

    セキュリティ

    SUID(Set User ID)
    所有者がrootユーザーであるプログラムにSUID(Set User ID)を設定すると、一般ユーザーが実行した場合でも、そのプログラムはroot権限で動作します

    chageコマンド
    有効期限の設定はchageコマンドで行います。

    オプション
    -l –list有効期限を表示
    -m –mindaysパスワード変更日数の最低日数を設定
    -M –maxdaysパスワードの最大有効期限日数を設定
    -d –lastdayパスワードの最終更新日を設定
    -W –warndays有効期限切れが何日前から警告するか設定
    -I –inactive有効期限後アカウントがロックされるまでの日数を設定
    -E –expiresdateアカウントが無効になる日付を指定

    whoコマンド
    ユーザーのログイン状況やログイン履歴を把握することで、不審なログインを見つけ出すことができます。ログイン中のユーザーを調べるには、whoコマンドを使います。

    wコマンド
    wコマンドを使うと、ログイン中のユーザーに加え、システム情報も表示されます

    lastコマンド
    lastコマンドを使うと、最近ログインしたユーザーの一覧を表示します。


    開いているポートを確認するには、netstatコマンドやssコマンド、lsofコマンドを使います。

    netstatソケット、インターフェイスごとのネットワーク統計など表示
    ss「ソケット」についての情報などを表示
    ※従来から移行 netstat → ss
    lsoflsofコマンドは、プロセスが開いているファイルを表示するコマンドですが、
    -iオプションを指定すると、開いているポートを確認できます。実行にはroot権限が必要です。
    nmap攻撃者がネットワーク経由で開いているポートを確認する行為をポートスキャンといいます。nmapコマンドでポートスキャンを行えます
    fuserポートを開いているプロセスを特定するには、fuserコマンドも使えます。


    /bin/false
    /sbin/nologin
    ユーザーのログインシェルを/bin/falseや/sbin/nologinに変更すると、一般ユーザーのログインを禁止することができます。

    ulimitコマンド
    ulimitコマンドを使うと、ユーザーが利用できるリソースを制御できます。

    オプション
    -a制限の設定をずべてひょうじ
    -c サイズコアファイルのサイズを指定
    -f サイズシェルが生成できるファイルの最大サイズを指定
    -n 数同時に開けるファイル数を指定
    -u プロセス数ユーザが利用できる最大のプロセス数を指定
    -v サイズ最大仮想メモリサイズ

    suコマンド
    suコマンドを使うと、一時的に別のユーザーになることができます。

    sudoコマンド
    特定の管理者コマンドのみの実行を許可したい場合は、sudoコマンドが利用できます。sudoコマンドを使えば、任意の管理者コマンドを任意のユーザーに許可することができます。


    inetd
    xinetd
    常駐するデーモンの数が多くなると、待機中のデーモンが消費するシステムリソースもそれだけ大きくなります。
    inetdやxinetdといったスーパーサーバーは、他のサーバープログラムに代わってサービス要求を監視し、接続が確立した時点で本来のサーバープログラムに要求を引き渡します。

    /etc/xinetd.conf
    xinetdの設定は、全体的な設定を行う/etc/xinetd.confファイルと、xinetd.dディレクトリ(通常は/etc/xinetd.d)以下にあるサービスごとの設定ファイルから構成されます。

    /etc/inetd.conf
    inetdの設定ファイルは/etc/inetd.confです。1行につき1つのサービスを設定します。サービスを無効にするには、該当するサービスの行頭に「#」を記述しコメント化します。

    /etc/nologin
    /etc/nologinファイルを作成しておくと、rootアカウントによるログイン以外は禁止されます。

    Netfilter
    Linuxカーネルには、Netfilterというパケットフィルタリング機能が備わっています。

    iptablesコマンド
    iptablesコマンドを使ってパケットフィルタリングのルールを細かく設定することができます。

    firewalld
    CentOS 7以降では、ファイヤウォールサービスとしてfirewalldが搭載されました。

    firewall-cmd –remove-service=dhcpv6-client
    ※ 即座に設定が反映されますが、再起動等の reload 時に設定が戻ってしまいます。
    →設定が戻らないようにするには –permanent を付け加えます。

    firewall-cmd –permanent –remove-service=dhcpv6-client
    ※ 設定は恒久的に残りますが、即座には反映されません
    →reload 等が必要です。

    「–zone=ゾーン」を指定しない場合は、デフォルトのゾーン(初期値はpublic)についての操作になります。

    sshに使われる暗号化アルゴリズム

    アルゴリズム
    RSA広く普及
    DSA広く普及、安全性に懸念あり
    ECDSA小さな鍵長、高速
    ED25519安全性が高い、高速、DSAやDCDSAより安全性が高い

    ssh-keygen
    公開鍵と秘密鍵のペアを作成する


    GnuPG(GNU Privacy Guard)
    ファイルを暗号化したい場合利用

    gpg コマンド
    GnuPG
    を利用するために使います。

    ホスト認証

    1. ホスト公開鍵を登録

    オープンソースの文化

    コピー
    レフト
    GPLフリーソフトウェア財団(FSF)
    AGPLインターネット経由でもソースコードの開示を要求
    LGPLライブラリ用
    MPLMozilla Foundation
    BSD License×カリフォルニア大学のバークレー校
    MIT License×マサチューセッツ工科大学
    Apache License×Apacheソフトウェア財団(ASF)
    いずれのライセンスでも著作権免責事項表記が義務付けられている
    ワイヤーフレーム、デザインカンプとは

    ワイヤーフレーム

    ワイヤーフレームとはWebサイトのレイアウトを決めるものです。

    デザインやコーディングに入る前に、作成し完成イメージを共有します。

    デザインカンプ

    デザインカンプとは「Design Comprehensive Layout」の略です。

    サイト制作では、クライアントにデザインカンプをいくつか提案し、採用されたものを元に製作を進めるのが一般的な流れとなります。

    Sass導入方法

    Sassとは

    Scssのメリット

    CSSを効率よく書けることや管理、メンテナンスが楽になることがあります。

    • 変数
    • ネスト記法
    • mixin
    • 関数

    Sass導入方法

    SassはCSSと違いHTMLファイルで読み込めないので、CSSファイルにコンパイルする必要があります。

    よく紹介されている、VSCodeの拡張機能Live Sass CompilerはDartSassに非対応です。

    またDartJS Sass Compiler and Sass Watcherという拡張機能もあるのですが、個人的にパスの設定等が難しく感じました。

    そこで今回はVSCodeの拡張機能をしようせず、Sassをコンパイルする方法を紹介します。

    1)パソコンにNode.jsをインストールする

    Node.js公式サイトからダウンロードしインストールします。

    インストールされているか、過去にインストールしていたかの確認はコマンドを打つことで調べれます。

    Macの場合ですと、ターミナルで行います。

    画面上部の虫眼鏡のアイコンで「ターミナル」と検索します。

    一応現在のディレクトリを確認します。

    pwd
    node -v

    node.jsのバージョンが分かります。

    バージョンが表示されていれば、インルトールされていることが分かります。

    2)作業するフォルダ(ディレクトリ)を作成

    作成する内容は以下の通りです。

    • sass-lesson(作業フォルダ)
      • src
        • style.scss
      • index.html(任意)

    2)VSCodeで作業フォルダにてSassをインストール

    ▼ VSCodeでターミナルを開く

    VSCodeのメニューでターミナルを選ぶと現在作業しているディレクトリにいる状態で開いてくれます。

    そのまま作業ディレクトリ上でコマンドを入力します。

    ▼ npmをインストール

    npm init -y

    ※init…(イニシャライズ)初期化の意味

    コマンドを入力するとpackage.jsonが生成されます。

    ▼ Sassパッケージをインストール

    npm install --save-dev sass

    コマンドを入力するとnode_modules、package-lock.jsonが生成されます。

    package.jsonとは手順を共有することができるもので、料理のレシピのようなものですが、

    中身を見るとSassが追加されていることが確認できます。

    3)コンパイルする

    ▼ コンパイルるすためpackage.jsonの内容を書き換えます。

    "scripts": {
        "sass": "sass src/style.scss css/style.css"
    },

    ▼ コンパイルする

    npm run sass

    先ほどpackage.jsonに書いた”sass”を実行したということです。

    正常にCSSが生成されました

    【VSCode】Visual Studio Code ショートカット

    ショートカットキー

    カーソルがある行を複製

    • macOS:Ctrl + Shift + ↑/↓、
    • Windows:Shift + Alt + ↑/↓

    すべて折りたたむ

    Ctrl+K Ctrl+0

    全て折りたたまれており一つずつ展開して使用すると素早く作業できます

    何の閉じタグかを分かりやすくする方法

    タグ名.クラス名|c

    figma

    ショートカットキー

    Fnキー + Fフレームの作成
    shiftキー + Fガイドの表示切り替え
    shiftキー + 矢印10pxずつ移動
    command + Gグループ化
    option + command + Gフレーム化
    command + [再背面へ移動

    コピー&ペーストについて

    command + shift + V貼り付け先のスタイルにあわせてペースト
    command + shift + C → command + V貼り付け元のスタイルのみ貼り付け

    レイアウトグリッド

    レイアウトグリッドのが使いやすいです。

    12列にすると、2、3、4カラムで使えて便利です。

    余白の設定もできるので、max-width: 〇〇pxのコンテナ幅でデザインを作成する場合に便利です。

    コンポーネント機能でフッターメニューを作成

    1)メニュー(top、about、service、faq、contact)からひとつフッターエリアへ移動しテキストの色を変更し、フレーム化します(option + command + G)

    2)オートレイアウト化し、左右の余白を調整

    右側だけ線を付けます

    3)コンポーネント化します。

    4)コンポーネント化したものをまとめる場所に移動させ、複製し元の場所に戻します。

    5)複製し、テキストをコピーします。(command + shift + V …スタイルはコピーしない)

    6)オートレイアウト化します。

    オートレイアウト化することで隙間をそろえて先ほど作成した、コンポーネントを調節することでフッターメニュー全てが一括で変更できます。

    このようにデザインする際コンポーネント化し、それを制作物のフレームと別のフレームで管理すると便利です。

    コンポーネント化解除したいとき

    コンポーネント化したものを編集したい時など、解除したいときはあると思います。

    コンポーネント化を解除することはできないので、一度インスタンス化したものを右クリック→メニューから[インスタンスの切り離し]選択し、フレームに戻します。

    便利プラグイン

    https://note.com/itaru_cgart/n/n76a451cf2619
    CSSサンプルコードまとめ

    display: flex;

    row左から右への横並び
    column上から下
    row-reverserowの逆
    column-reversecolumnの逆
    <flex-directionプロパティ>

    flex-shrink

    flexアイテムの縮小率を指定するプロパティです。親要素のflexコンテナからはみ出た要素を縮小することができます。

    また幅を縮めたくないときは、flex-shrink: 0;を指定します。

    親要素にdisplay: flex;を指定し、子要素にflex-shrinkを指定します。

    flex

    flexとは、flex-growflex-shrinkflex-basisを同時に指定できるプロパティです。

    flex: 1;

    flex-grow: 1;flex-shrink: 1;flex-basis: 0;を同時に指定できるプロパティです。

    flex-grow: 1;親要素の余っているスペースを整数で設定した比率で分配
    flex-shrink: 1;親要素からはみ出たスペースを整数で設定した比率で縮める
    flex-basis: 0;width、heightのように幅を初期値を設定できる
    デフォルト値=autoを0で記載
    https://miyattiblog.com/explanation-of-flex-property/

    gapプロパティー

    gapプロパティーはFlexboxおよびGridで要素間の間隔を設定できます。

    display: grid;

    CSS Gridで中央揃え

    .sample {
    background: #222;
    color: #fff;
    display: grid;
    place-items: center;
    padding: 60px;
    }
    gridで中央寄せ
    https://developer.mozilla.org/ja/docs/Web/CSS/grid-template-columns

    よく使うコード

    https://ntorelabo.com/?p=4671#co-index-68

    リスト 左寄せ揃えかつ中央寄せ

    • リストを
    • 左の書き出し位置は揃えつつ
    • 画面中央位置に寄せたい場合

    ▼ulの親要素、ulに下記のスタイルをあてる

    .list-center {
    text-align: center;
    }
    .list-center ul {
      text-align: left;
      display: inline-block;
    }
    • リストを
    • 左の書き出し位置は揃えつつ
    • 画面中央位置に寄せたい場合

    カラム子要素 下揃え

    各カラムでテキストの量に違いがあったりする場合、カラム下部子要素の高さ位置がバラバラになってしまうことがあると思いますが、CSSで下ぞろえにすることができます!

    各カラムで下部子要素の高さをそろえたいとき、CSSで可能です!

    各カラムでテキストの量に違いがあったりする場合、カラム下部子要素の高さ位置がバラバラになってしまうことがあると思いますが、CSSで下ぞろえにすることができます!

    
    .columns-f .wp-block-column {
    display: flex;
    flex-direction: column;
    }
    .columns-f .wp-block-column div:last-child {
    margin-top: auto!important;
    }

    各カラムでテキストの量に違いがあったりする場合、カラム下部子要素の高さ位置がバラバラになってしまうことがあると思いますが、CSSで下ぞろえにすることができます!

    各カラムで下部子要素の高さをそろえたいとき、CSSで可能です!

    各カラムでテキストの量に違いがあったりする場合、カラム下部子要素の高さ位置がバラバラになってしまうことがあると思いますが、CSSで下ぞろえにすることができます!

    その他

    https://find-a.jp/seotimes/11-flow-designs
    https://jito-site.com/flexbox-bottom-alignment-button/
    【WordPress】カスタムフィールド作成の仕方「ACF」Advanced Custom Fieldsの使用法

    そもそもカスタムフィールドとは

    WordPressの投稿画面にはタイトル、本文、抜粋といった項目がもともとありますが、カスタムフィールド機能はさらに追加で新しい入力項目を設定することができます。

    • WordPressに詳しくない人でも編集がしやすくなります。
    • データ管理しやすくなります。

    例)「求人投稿」というカスタム投稿があった場合

    仕事内容、応募条件などの情報をカスタムフィールドに設定

    →投稿者さんが簡単に編集できるようになります

    カスタムフィールド作成の仕方「ACF」Advanced Custom Fieldsの使用法

    1)「ACF」Advanced Custom Fieldsをダウンロード

    ▽「新規プラグインを追加」より、「Advanced Custom Fields」をダウンロード → 「有効化」

    https://ja.wordpress.org/plugins/advanced-custom-fields

    2)フィールドグループを作成

    〇フィールドグループを新規作成

    ワードプレス管理画面メニュー「ACF」より「フィールドグループ」をクリック

    ▽「新規追加」か「フィールドグループを追加する」をクリック

    〇フィールドグループの各フィールドを入力

    ▽フィールドの各項目を入力

    例)

    • フィールドグループタイトル:工房情報
      • 全般
        • フィールドタイプ:テキスト
        • フィールドラベル:所在地
        • フィールド名:location
        • 初期値:未記入
    フィールドタイプテキスト、画像、ラジオボタン等あります
    フィールドラベル編集ページに表示されます
    フィールド名テンプレートファイルを編集する際に使用
    初期値新規投稿作成時に表示されます

    ▽フィールドグループの各項目を入力

    例)

    • フィールドグループタイトル:工房情報
      • 検証
        • 必須項目:未記入
        • 文字数制限:未記入

    ▽「フィールドを追加」

    同様の手順で下記の通りフィールドを入力しました

    例)

    • 全般
      • フィールドタイプ:画像
      • フィールドラベル:アイコン画像
      • フィールド名:img_icon
    • 戻り値の形式:画像配列
    • ライブラリ:すべて

    〇フィールドグループの設定

    カスタムフィールドを表示するために「ルール」を設定できます

    プラグイン「Custom Post Type UI」で作成したカスタム投稿タイプのときだけ表示することもできます

    3)カスタムフィールドを使用した記事を投稿する

    ▽作成したカスタムフィールドが表示されるので、入力し記事を公開

    4)作成した記事カスタムフィールドの表示

    WordPressテーマ「SWELL」使用している場合、フィルターフックによる方法がオススメです

    ▽functions.phpを編集(ひとまずフィルターフックの出力を確認)

    add_filter('the_content', function() {
    	if (is_singular('workshop')) {
    		$html  = $the_content;
    		$html  .= '出力するコード';
    		return $html ;
    	}
    });

    下記の通り$the_content直下に表示させることができます

    ▽functions.phpを編集(カスタムフィールドの出力)

    add_filter('the_content', function($the_content) {
    	if (is_singular('workshop')) {
    		
    		// ACFで設定した画像を取得 ※関数内で宣言
    		$Landscape = get_field('landscape');
    		$ImgIcon = get_field('img_icon');
    
    		$html  = $the_content;
    		$html .= '<div class="work-shop-landscape" style="background: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.4)), url('.$Landscape['url'].');"></div>';
    		$html .= '<img class="work-shop-img-icon" src="'.$ImgIcon['url'].'">';
    		$html .= '<p>'.get_field('location').'</p>';
    		return $html;
    	}
    
    	// トップページで何も表示されなくなるため
    	else {
    		return $the_content;
    	}
    });

    Advanced Custom Fieldsの画像フィールドの使い方と応用方法
    https://usagicode.com/wordpress/how-to-use-acf-image-field/

    【SWELL 】カスタムフィールドの値を詳細記事テンプレート(single.php)に表示するカスタマイズ
    https://note.com/swell_mania/n/n9d7f8ea13eb2

    方法(2)foreach文を入れる場合方法(1)の記述方法がわからないので、アクションフックを使用した出力方法で

    ▽functions.phpを編集

    add_action('the_content', function($html) {
    	if(is_singular('workshop')) {
    		// ACFで設定した画像を取得 ※関数内で宣言
    		$Landscape = get_field('landscape');
    		$Icon = get_field('img_icon');
    		$Loction = get_field('location');
    		?>
    		<div class="work-shop-landscape" style="background: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.4)), url(<?php echo esc_attr($Landscape['url']); ?>);"></div>
    		<div class="work-shop-headerInfo">
    			<div class="work-shop-icon-wrapper"><img class="work-shop-icon" src="<?php echo esc_attr($Icon['url']); ?>"></div>
    			<div class="work-shop-icon-desc">
    				<div class="work-shop-tag">
    					<?php 
    						$terms = get_the_terms($post->ID, 'area');
    						if ($terms) {
    							foreach ($terms as $term) {
    								// echo '<a class="tagc-area" tag-id="' . $term->term_id . '" href="' . get_permalink() . '">' . $term->name . '</a>';
    								// aタグのリンクを無効
    								echo '<a class="tagc-area" tag-id="' . $term->term_id . '" href="">' . $term->name . '</a>';
    							}
    						}
    						$terms = get_the_terms($post->ID, 'tag-workshop');
    						if ($terms) {
    							foreach ($terms as $term) {
    								// echo '<a class="tagc-tag-workshop" tag-id="' . $term->term_id . '" href="' . get_permalink() . '">' . $term->name . '</a>';
    								// aタグのリンクを無効
    								echo '<a class="tagc-tag-workshop" tag-id="' . $term->term_id . '" href="">' . $term->name . '</a>';
    							}
    						}
    					?>
    				</div>
    				<!-- /.work-shop-tag -->
    				<div class="work-shop-location"><?php echo esc_attr($Loction); ?></div>
    				<!-- /.work-shop-location -->
    			</div>
    			<!-- /.work-shop-icon-desc -->
    		</div>
    		<!-- /.work-shop-headerInfo -->
    		<?php
    	}
    
    	// トップページで何も表示されなくなるため
    	else {
    		return $html;
    	}
    });
    https://olein-design.com/blog/ways-to-use-custom-fields-with-snow-monkey

    【WordPress】本文入力欄を非表示にする方法

    https://ntorelabo.com/?p=11426

    参考サイト

    【完全版】Snow Monkeyでカスタム3兄弟を実装する 
    https://ippei-kusakari.com/web/snow-monkey/custom-post

    Advanced Custom Fieldsの画像フィールドの使い方と応用方法
    https://usagicode.com/wordpress/how-to-use-acf-image-field/

    【SWELL 】カスタムフィールドの値を詳細記事テンプレート(single.php)に表示するカスタマイズ
    https://note.com/swell_mania/n/n9d7f8ea13eb2

    【サンプルコード付き】カスタムフィールドの値を一覧ページに表示するカスタマイズ
    https://webrent.xsrv.jp/display-customfield-on-archive-pages

    カスタムフィールドの値でソートをかける方法

    <?php /* 取得する投稿の条件 */ ?>
        <?php
        $args = array(
            'post_type' => 'post', /* 取得したい投稿タイプ */
            'category_name'  => 'job',
            'posts_per_page' => -1, /* 表示したい投稿の数 (すべての取得したい場合は「-1」) */
            'orderby' => 'meta_value', 
            'meta_key' => 'price', //ここにソートの対象となるカスタムフィールドの名前を
            'order' => 'DESC'
        );
        $the_query = new WP_Query($args); /* クエリの作成と発行をし、取得したデータを「$the_query」に格納 */
        ?>

    テーブルのソートはWordPressのプラグインで便利なものがあります。

    table要素のクラス名をtablesorterとすればOK

    headerAheaderBheaderC
    1中央区30万
    2港区20万
    3千代田区25万
    4中央区20万
    https://wordpress.org/plugins/table-sorter
    【初心者】Excelよく使う関数

    業務の効率化を考える上で関数はすごく便利、とくによく使うものを今回ご紹介します。

    DATE関数

    「年」、「月」、「日」を引数に指定し、日付を作成する関数

    =DATE(年,月,日)

    Word、Excelの小技

    改ページ位置の設定

    見出しとその内容が別のページに分かれてしまう場合があります。

    見出しと内容をまとめて、次のページから開始するようにせっていすることができます。

    ホームタブ → 段落グループ → 段落の設定 → 改ページと改行タブ → 次の段落と分離しないを✓にします

    複数行の文字を前で囲む方法

    1. 囲みたい複数行を選択する
    2. 「Alt」→「A」→「B」
    3. 「線種とページ罫線と編みかけの設定」を表示
    4. 「罫線タブ」で囲む→OK

    Excelのセルの連番入力

    「Ctrl」を押しながら、セルの右下をドラッグ

    行の高さの自動調整

    ホームタブ→セルの書式にて設定

    インフラエンジニアとは

    そもそもインフラとは

    インフラとはインフラストラクチャー(Infrastructure)の略です普段の生活の基盤を意味します。

    例えば公共交通機関、公共施設、電気・ガス・水道など、日々の暮らしにに欠かせない設備です。

    インフラエンジニアとは

    インフラエンジニアはその名の通り、インフラストラクチャーを管理するエンジニアです。 IT環境の下支えをするようなイメージです。

    ネットワーク、サーバーなどを設計・構築・運用・保守を手がける技術者がインフラエンジニアです。

    インフラエンジニアの中でもいくつか分かれますが、分かりやすく2つに大別すると下記の通りです。

    • サーバエンジニア
    • ネットワークエンジニア
    • セキュリティエンジニア

    システムエンジニア(SE)との違いは?

    インフラエンジニアと似た職種に、システムエンジニア(SE)があります。

    インフラエンジニアサーバーやネットワークなどのIT基盤を扱うのに対し、システムエンジニアはソフトウェアやアプリケーションなど主にシステムの開発を行う技術者です。

    インフラエンジニアが構築した基盤の上で動作するシステムをシステムエンジニアが開発・運用するという関係です。

    インフラエンジニアの種類

    先ほども紹介したように、インフラエンジニアは担当する領域や業務内容によって、いくつかの種類に分かれます。主に次のような種類があります。

    個人的にはインフラエンジニアの最初の仕事はサーバエンジニアよりの仕事が多いのかなと思っています。 理由としては、そこまで知識がなくてもなんとなくわかるからです。(一方、ネットワークエンジニアはネットワークに関する知識が必要なので少し専門的ですね。)

    具体的な仕事内容は様々ですが、基本的には下記に分類されるかと思います。(下に行くほど高難度です)

    • 運用保守
    • 構築
    • 設計

    サーバーエンジニア

    サーバーの構築や運用、保守を行います。

    メールサーバーやWebサーバー、DBサーバーなどさまざまなサーバーを設計・構築したり、障害が発生した時の対応を含めた運用・保守を行います。

    また、サーバー機器をラックに設置したり、他の機器とケーブルの配線等、物理的な作業もします。

    ネットワークエンジニア

    コンピューターなどの機器をルーターやLANケーブルでつなぎ、ネットワーク環境を設計・構築・運用します。

    作成した設計書に基づいたネットワーク環境を作り、トラブルや不具合がないようチェックしながら運用・保守を行います。

    セキュリティエンジニア

    情報セキュリティに特化したエンジニアです。

    • セキュリティ機器を導入
    • サイバー攻撃やウイルス感染の防止

    インフラエンジニアの給料や残業

    給料面はインフラエンジニアは全エンジニアの中では平均的かと思います。 (感覚になりますが、平均年収450〜550くらいのレンジかと) が、尖ったスキルがあると給料は青天井です。

    例えば、 「クラウドの中でもAWS(Amazonが出しているサービス)は誰にも負けません」 だったり、 「ネットワークの知識は誰にも負けないので、設計から構築、運用まで任せてください」 などです。

    これは専門職なので当然の流れではありますが、広く浅くよりも狭く深くの方が希少な人材として給与が高くなる傾向があると思います。

    残業や深夜の仕事については、インフラエンジニアは大いにあり得ると考えていただいた方が良いです。 特にサーバを更新、停止する際は長期休暇などを利用することが多いです。

    また、サーバ停止などによって業務がストップした場合は、緊急で呼び出されたりすることもあります。 なので、一般的なインフラエンジニアは「激務だなぁ」と思われることが多いかもしれません。 ただ、これもポジションによって大きく変わります。 イメージとしては、末端の作業をするほど上記のような対応が多いです。 設計フェーズの上流対応であれば、残業はあるかもしれませんが、緊急対応などは少なくなりますね。

    インフラエンジニアに必要なスキル・知識

    ・自己研鑽を続けている

    IT業界は技術革新のスピードがとても速く、日々新しいテクノロジーが生まれています。

    ほかのエンジニア同様インフラエンジニアとして活躍するためには、日ごろから最新の技術をインプットし、自己研鑽を続けることが必要です。

    最近では、クラウド上の設計・構築のニーズが高まっています、そこで実務では経験がない人も、クラウド関連の資格で転職の際にアピール材料とすることも可能です。

    ・マネジメント経験がある

    インフラエンジニアとして一定のキャリアを積んだ人は、さらにチームマネジメントの経験が求められます。

    インフラエンジニアに必要な資格

    ・基本情報技術者試験/応用情報技術者試験

    情報処理に関する国家資格です。

    出題範囲はインフラ、セキュリティだけでなくIT全般となり、あらゆる知識の土台として有効です。

    ・CCNA/CCNP

    ネットワーク機器メーカーのシスコシステムズが提供するベンダー資格です。

    世界的に有名な資格であり、取得すればネットワークエンジニアとしての証明になります。

    ・LPIC/LinuC

    どちらもLinux技術者としての技術力を認定する資格です。

    特にLinuCは日本市場のニーズに合わせて開発された試験です。Linuxシステムの知識だけでなく、さらにクラウドシステムの知識、スキルを有した技術者であることの証明になります。

    ・AWS 認定ソリューションアーキテクト

    Amazonが提供するクラウドの知識を証明する中級レベルの認定資格です。AWSを一年以上使った実務経験者が対象となります。

    https://ntorelabo.com/?p=4144
    WP_Queryとは

    WP_Queryとは

    WordPressにはWP_Queryクラスというものがあり、データベースから投稿データを取得するためのクラスです。

    つまりSQL書かなくても色々な事ができるワードプレスで用意されているクラスです。

    WP_Queryクラスを正しく理解することがWordPressを使用するうえで重要なポイントです。

    WP_Queryクラスで投稿データを取得し、テンプレートタグに引き渡します。

    ただ WP_Queryクラスを直接インスタンス化するこはあまりありません、かわりにメインクエリによる検索、get_posts()などの関数を使う方法が一般的で便利です。

    メインクエリとは

    リクエストパラメータからデータを検索することをメインクエリといいます。

    リクエスト例

    • http://mysite○○.com/inedex.php?p=5099(IDが5509の記事のリクエスト)
    • http://mysite○○.com/inedex.php?cat=8(カテゴリーのIDが8の記事のリクエスト)

    テンプレートタグとは

    メインループで取得したデータを表示したり、テンプレートパーツを呼び出したりすることができます。

    インクルード系テンプレートパーツの呼び出し
    get_header()、get_sidebar()
    コンテンツ系データベースから取得したコンテンツを表示
    the_title()、the_content()
    タグ出力系wp_head()、wp_footer
    条件分岐タグ系ページの種類を判別
    is_home()

    WordPressで定義されたPHPの関数です。

    https://ntorelabo.com/?p=6744#co-index-1

    クエリフラグの保持

    WP_Query クラスの役割のひとつがクエリフラグの保持となります。

    現在のクエリがどのページの種類か判別するためのものがクエリフラグです。

    ページの種類

    リクエストに対して出力されるページの種類は決まっています。

    • アーカイブページ(カテゴリー別、日時別、カスタムタイプ投稿別…)
    • 個別ページ(投稿ページ、固定ページ)
    • サイトフロントページ
    • ブログメインページ
    • 検索結果ページ
    • 404エラーページ
    • コメントポップアップページ

    メインループとサブループとは

    サブループは記事のサイトバーによくある投稿一覧を表示させるとき使用します。

    https://wordpress-web.and-ha.com/subloop-with-wp_query/

    WP オブジェクトの main() メソッド

    public function main($query_args = '') {
     $this->init();
     $this->parse_request($query_args);
     リクエストの内容を解析し変数$wp->query_varsに保存
    
     $this->send_headers();
    
     $this->query_posts();
     変数$wp->query_varsを使いメインクエリを実行
    
     $this->handle_404();
     $this->register_globals();
     do_action_ref_array('wp',array(&this));
    }

    テンプレートの選択

    リクエストパラメータからデータを取得したら、テンプレートの読み込みが行われます。

    テンプレートの読み込みはテンプレート階層から、最初に見つかったファイルがロードされます。

    テンプレートファイルは親テーマより子テーマに置かれているものが優先されます。

    テンプレートタグ

    WordPressにはテンプレートファイルでデータの出力に使う、テンプレートタグと呼ばれるPHPの関数が用意されいます。

    the_ID()、post_class()、the_title() … 頭にtheがつくものはデータを出力するもの、getがつくものはデータを取得をするものが多いです。

    条件分岐タグ

    テンプレート内でそのページが何であるか確認、条件分岐することができる関数を条件分岐タグとよばれるPHPの関数が存在します。

    is_archive()、is_singular()、is_category()…

    インクルードタグ

    インクルードタグは別のテンプレートをロードするための関数です。

    get_header() get_footer() get_template_part()

    リポジトリとパッケージ管理

    パッケージ管理とは

    パッケージとはソフトウェアの実行プログラム、設定ファイルなどをまとめたです。

    ソフトウェアのインストールはパッケージごとに行い、パッケージの管理方法はディストリビューションで変わってきます。

    パッケージ管理システム

    パッケージのインストール、アンインストール、アップデートの仕組みを提供します。

    代表的なパッケージ管理システム

    • Debian形式(Debian GNU/LinuxやUbuntuなど)
    • RPM形式(Red Hat Enterprise LinuxやCentOSなど)
    パッケージ管理システムディストリビューション扱えるパッケージ
    「yum」ヤムRed Hat系(Cent OSなど)RPM系パッケージ
    「apt」Debian系(Ubuntsだど)deb系パッケージ

    Debianパッケージ管理

    Debian系のディストリビューションはDebian形式のパッケージ管理方式を使います。

    dkpgコマンド

    dpkg→Debian Packageの略

    dkpg オプション アクション

    オプション
    -Eすでに同バージョンがインストールされている場合インストールを行わない
    -Gすでに新バージョンがインストールされている場合インストールを行わない
    -Rディレクトリ内を再帰的に処理
    アクション
    -i –install パッケージファイル名インストール
    -r –remove パッケージ名設定ファイルを残してパッケージをアンインストール
    -p –purge パッケージ名設定ファイルも含めてパッケージをアンインストール
    -l –list 検索パターンインストール済みのパッケージを検索して表示
    -L –listfiles パッケージ名指定したパッケージからインストールされたファイルの一覧を表示
    -s –status パッケージ名インストール済みのパッケージの詳細情報を表示
    -S –Search 検索パターン指定したファイルがどのパッケージからインストールされたかを表示
    -C –auditインストールが完了していないパッケージを表示

    dpkg-reconfigure

    dpkg-reconfigureコマンドを使うと、対話的な設定を実施することができます。

    インストール済みのパッケージを再設定する

    aptコマンドによるパッケージ管理

    APTコマンドは、dpkgツールを拡張した、Debian系パッケージを管理することができます。

    apt-getコマンド

    APT(Advanced Packaging Tool)というパッケージ管理ツールのコマンドです。

    依存関係を考慮しながらパッケージのインストール、アップグレード、アンインストールを行います。

    apt-get [オプション] サブコマンド パッケージ名

    install パッケージ名インストールまたはアップグレード
    remove パッケージ名アンインストール
    upgrade既存のパッケージの削除や新規のパッケージを追加せずに更新可能なものをアップグレード
    dist-upgradeシステム全体をアップグレード
    upgdateパッケージのデータベースを最新版に更新
    clean過去のパッケージファイルを削除

    apt-cacheコマンド

    APTツールでDebian形式のパッケージ情報の検索・参照などを行います。

    search キーワード指定したキーワードを含むパッケージを検索
    show パッケージ名パッケージの一般的な情報を検索
    showpkg パッケージ名パッケージの詳細な情報を検索
    depends パッケージ名指定したパッケージの依存関係情報を表示
    pkgnamesすべてのdebパッケージ一覧を表示

    apt-fileコマンド

    apt-fileコマンドは、指定したファイルが含まれているパッケージを検索します。

    updateパッケージ情報を最新版に更新
    search、find 検索パターンパスに検索パターンがあるファイルを含むパッケージを検索
    list、show パッケージ名パッケージに含まれているファイル一覧を検索

    yumコマンドによるパッケージ管理

    yum

    ソフトウェアパッケージの管理をするプログラムです。

    依存関係を調整しながら、インストール・アンインストールなどを行います。

    installパッケージのインストール
    updateパッケージのアップデート
    removeパッケージのアンインストール
    infoパッケージの詳細情報を表示
    listパッケージ一覧を表示
    searchキーワードでパッケージを検索
    grouplistパッケージグループの一覧を表示
    groupinstallパッケージグループのインストール
    deplist指定したパッケージが依存しているパッケージの一覧を表示

    /etc/yum.repos.d

    YUMの設定は、/etc/yum.confと/etc/yum.repos.dディレクトリでファイルで行います。/etc/yum.repos.dディレクトリにパッケージ取得元を設定するファイルが格納してあります。

    RPMパッケージ管理

    rpmコマンドにはいくつかのモードがあります。

    • インストールモード
    • アンインストールモード
    • アップグレードモード
    • 照会モード
    オプション
    -i –installパッケージのインストール
    -U –upgradeパッケージのアップデート(なければインストール
    -F –freshenパッケージのアップデート(なければインストールしない
    -e –eraseパッケージのアンインストール
    併用オプション -v詳細情報を表示
    併用オプション -h –hash進行状況を表示
    併用オプション –test実際には実行せずテストで実施
    併用オプション –nodeps依存関係を無視
    オプション
    -q –query指定パッケージがパッケージがインストールされているか照会
    -V –vertify
    (併用オプションは-a、–nomd5のみ)
    パッケージの検査
    併用オプション -a –allインストール済みの全パッケージをの表示
    併用オプション -l –list指定したパッケージに含まれるファイルを表示
    併用オプション -i –info詳細情報を表示
    併用オプション -f –file ファイル名指定したファイルがどのパッケージからインストールされたか表示
    併用オプション -p –package照会対象をパッケージとする
    併用オプション –changelog変更履歴を表示
    併用オプション -c –configfiles設定ファイルの一覧を表示
    併用オプション –nomd5MD5によるファイルの改ざんの検査をしない
    GNUとUnixのコマンド

    コマンドラインの操作

    シェル

    入力されたコマンドを受け付け、対応するプログラムを実行しているプログラムをシェルといいます。

    シェル変数

    変数を設定したシェル上でのみ有効な変数です。

    exportコマンド

    シェル変数を環境変数に変更します。

    操作シェル変数環境変数
    設定変数名=値export 変数名
    export 変数名=値
    declare -x 変数名=値
    表示setenv
    削除unset 変数名unset 変数名

    環境変数

    シェル上に加えてそのシェル上で起動した子プロセス(アプリケーション、コマンド)でも有効です。

    シェルの種類やコマンド検索のパス等、動作に影響する設定値です。

    HISTFILEコマンド履歴保存ファイルのパス
    HISTSIZE現在のシェルでのコマンドの保存数
    HOMEログインしているユーザのホームディレクトリ
    PATHコマンドやプログラムを検索するディレクトリのリスト
    PWDカレントディレクトリのパス

    引用符

    「’」シングルクォーテーション

    文字列と解釈

    「”」ダブルルクォーテーション

    文字列と解釈し、変数を展開します。

    またバッククォーテーションが使われている場合、その中も展開されます。

    「\」バックスラッシュ

    バックスラッシュ直後の文字は文字列と解釈され、展開されません。

    バックスラッシュは文字とよばれます。

    「`」バッククォーテーション

    コマンドは実行結果が展開されます。

    メタキャラクタ

    シェルによって特別に解釈される文字をメタキャラクタといいます。

    メタキャラクタ
    *0文字以上の文字列
    ?任意の1文字
    [][~] 内の任意の1文字
    [!~] 以外の任意の1文字

    フィルタを使ったテキストストリームの処理

    cat

    ファイルの内容を標準出力に出力します。concatenate ( つなぐ、連結する )

    -n –number各行の左に番号を付与

    od

    バイナリーファイルを8進数や16進数で表示します。(デフォルトは8進数)

    -t -format 出力ファイル出力するフォーマットを指定
    出力タイプ
    cASCⅡ文字
    o8進数(デフォルト)
    t16進数

    paste

    1つ以上のファイルを読み込み、行ごとに水平方向に連結します。

    区切り文字はデフォルトでタブ

    -d 区切り文字区切り文字を指定(デフォルトはタブ)

    paste [ オプション ] ファイル名1 ファイル名2 …

    join

    2つのファイルを読み込んで、共通のフィールドを持つ行どうし連結します。

    join [ オプション ] ファイル名1 ファイル名2

    -j フィールド連結するフィールドを指定

    fmt

    テキストを1行あたり決められた桁数に整形します。

    -w 1行の文字数を指定

    ストリーム、パイプ、リダイレクトの使用

    リダイレクト

    通常コマンドの実行結果は画面上に表示されますが、リダイレクトは実行結果をファイルに保存したり、用意しておいたファイルに使用する場合に使います。

    コマンド>ファイルコマンドの標準出力をファイルに書き込む
    コマンド<ファイルファイルの内容をコマンドの標準入力に送る
    コマンド>>ファイルコマンドの標準出力をファイルに追記
    コマンド<<終了文字終了文字が現れるまで標準入力へ送る
    コマンド1|teeファイル|コマンド2コマンド1の出力結果をコマンド2の標準入力に渡し、併せてファイルに書き込む

    tee

    teeコマンドは標準入力の内容を、Tの字のように、標準出力先とファイルの両方に出力するコマンドです。

    通常、|(パイプ)と使用します。コマンドの標準出力をteeコマンドの標準入力に渡します。

    コマンド | tee ファイル

    xargs

    あるコマンドの出力を、別のコマンドの引数として実行します。

    正規表現を使用したテキストファイルの検索

    正規表現

    .任意の1文字
    *直前の文字列の0回以上の繰り返し
    [][]内の1文字、-は範囲指定、^は後続の文字列以外
    ^行頭
    $行末
    \次の文字をエスケープ(通常の文字として処理)
    +直前の文字を1回以上繰り返し
    ?直前の文字を0、1回の繰り返し(拡張正規表現)
    |左右どちらかの文字列(拡張正規表現)

    grep

    検索文字列があるかどうか調べます。

    -c –countマッチした行数を表示
    -f –file検索パターンをファイルから読み込む
    -i –ignore-case大文字小文字区別しない
    -n –line-number併せて行番号も取得
    -v –invert-matchマッチしない行を表示
    -E –extended-regexp拡張正規表現を使用(egrepと同様)
    -F固定文字列とする(fgrepと同様)

    sed

    stream editor

    オプション
    -f ファイルコマンドに書かれたスクリプトファイルを指定
    -i処理した内容でファイルを上書き
    -e編集コマンドを指定(1つの場合省略可能)
    sed オプション -e 編集コマンド1 -e 編集コマンド2 ファイル名
    sコマンド(置換)
    s/文字列1/文字列2/各行の最初に現れる文字列1を文字列2に置換
    s/文字列1/文字列2/gすべての文字列1置換
    s/文字列1/&を含む文字列2/&に文字列1を再利用
    dコマンド(置換)
    /文字列/d文字列が含まれる行を削除
    行番号1,行番号2d行番号1から行番号2までの行を削除

    エディタを使った基本的なファイル編集の実行

    viエディタ

    テキストファイルを編集するときに使います。

    viの起動直後はコマンドモードになっています。

    vi [-R] [ファイル名]
    -Rオプションは読み取りモード、ファイル名を指定しなければ空の新規ファイルを作成します。

    入力モード

    iカーソルのある位置の左から入力 insert
    aカーソルのある位置の右から入力 append
    Iカーソルのある行の先頭から入力
    Aカーソルのある行の末尾から入力
    0カーソルのある行の上に空白行を挿入し、その行で文字を入力します。
    oカーソルのある行の下に空白行を挿入し、その行で文字を入力 open line

    カーソル操作

    h
    l
    k
    j
    O行の先頭へ移動
    $行の末尾へ移動
    H画面の一番上の行頭へ移動
    L画面の一番下の行頭へ移動
    ggファイルの先頭行へ移動
    Gファイルの最終行へ移動
    nG
    :n
    ファイルのn行目に移動

    編集コマンド

    yy Y (yank)行をバッファにコピーします。コマンドの直前に数字を付けると、その回数分viコマンドが繰り返されます。
    yw(word)カーソル位置の単語をコピーします。
    ddカーソル位置の行を削除し、バッファにコピー
    dw(dlelete word)カーソル位置から次の単語までを削除し、バッファにコピー
    xカーソル位置の文字を削除し、バッファにコピー
    Xカーソル位置の左の文字を削除し、バッファにコピー
    p(paste)バッファの内容を挿入します。文字はカーソルの右、行はカーソルの下に挿入されます。
    Pバッファの内容を挿入します。文字はカーソルの左、行はカーソルの上に挿入されます。
    u直前の操作をキャンセル

    :r 指定したファイルの内容をカレント行の後に読み込んで挿入する

    viエディタの終了、保存

    :q(quit)viを終了します、内容が変更されている場合警告が表示されます。
    :q!強制終了します。
    :w編集内容を保存
    :wq 😡 ZZ編集内容を保存し、終了
    :wq!編集内容を保存し、強制終了
    :e ファイル名viを終了せず、現在のファイルを閉じて別ファイルを開く
    内容が変更されている場合はファイルを開くことができない
    :e! ファイル名viを終了せず、現在のファイルを閉じて別ファイルを開く

    ファイル名を省略した場合、最後に保存した状態に戻す

    cat

    od

    sed

    head

    tail

    cut

    paste

    ハードウェア、ディスク、パーティション、ファイルシステム

    ハードウェアの基礎知識と設定

    基本的なシステム、ハードウェア

    CPU

    コンピュータの中心的な処理装置、Linuxは多くのCPUに対応している。

    メモリ

    コンピュータ内でデータを記憶する装置(メインメモリ、主記憶)です。電源が切れるとメモリの内容は消失します。

    Linuxを動作させるには512Mバイト~1Gバイト程度以上のメモリが推奨。

    ストレージ

    大きなサイズのデータや、長期の保存はストレージを使います。

    • ハードディスク(HDD:Hard Disk Drive)‥磁気ディスクに記憶する
    • SSD(Solid State Drive)‥フラッシュメモリに記憶する

    SATA(Serial ATA)現在主流の企画

    SAS(Serial Attached SCSI)SATAより高速、高信頼で高価。

    BIOS

    マザーボードに搭載されているプログラムです。

    (Basic Input Output System:入出力基本システム)

    UEFI

    現在ではBIOSの後継となるファームウェア規格のUEFI(Unified Extensible Firmware Interface)が普及している。

    カーネルモジュール

    カーネルモジュールとは、カーネルで扱う色々な機能を独立したパーツのようなものです。

    insmod

    insmodカーネルモジュールをロードするコマンドです。

    modprobe

    依存関係を考え、カーネルモジュールをロード、アンロードするコマンドです。

    rmmod

    rmmodコマンドは依存するモジュールは削除せず、指定したモジュールだけを削除します。

    依存関係を考慮してカーネルモジュールをアンロードする場合は、modprobe -r (–remove)を使用します。

    USBデバイス

    • HID(human interface device)‥キーボード、マウス
    • Mass Storage Class‥ハードディスク、USBメモリ
    • ACM Communication Device Class‥モデム、TA
    • Audio Class‥スピーカー、マイク

    udev

    udev(Userspace DEVice management)によって/devディレクトリ以下のデバイスファイルは自動的に作成されます。

    /procディレクトリ

    /procディレクトリ以下のファイルは、実体のない仮想ファイルです。テキストファイルです。

    /proc/cpuinfo

    CPUの情報は/proc/cpuinfoで確認できます。

    /proc/scsi/scsi

    SCSIデバイスの情報は/proc/scsi/scsiファイルで確認できます。

    /proc/meminfo

    メモリの使用状況は/proc/meminfoファイルでみることができます。

    /proc/dma

    デバイスが使用中のDMAチャネルの情報は/proc/dmaファイルでみることできます。

    lsusb

    lsusbは接続されたUSBデバイスの情報を表示するコマンドです。

    lspciコマンド

    lspci [オプション]

    -v 詳細表示(-vvでさらに詳細)

    1. PCI識別番号
    2. PCIデバイスの種類
    3. ベンダー名、ベンダーID
    4. デバイス名
    5. バスの速度(詳細表示のみ) 
    6. IRQ番号(詳細表示のみ) 
    7. I/Oポートアドレス(詳細表示のみ)

    PCI

    PCI‥Peripheral Components Interconnect

    PCIデバイスにはネットワークカード(NIC:Network Interface Card)などがあります。

    D-Bus

    Desktop Bus

    Linuxで使われるプロセス間通信機構でアプリケーション間のやり取りを行います。

    ファイルシステムの作成と管理

    ハードディスクのレイアウトとパーティション

    lvm

    Logical Volume Manager … 論理ボリューム管理

    仮想的なパーティションを動的に管理する機能です。

    • 論理ボリュームは複数のディスクにまたがって作成可
    • スナップショット(ある時点の記録)を取得が可能
    • 後からボリュームグループのサイズを変更可能

    パーティション管理コマンド

    fdisk

    パーティションの作成、削除、変更、情報表示

    MBR方式に対応

    -lオプション そのデバイスのパーティションテーブルの状態を表示します。

    mサイドメニューの表示
    lパーティションタイプの一覧表示
    nパーティションの作成
    dパーティションの削除
    pパーティションテーブルの表示
    tパーティションタイプ(システムID)の変更
    w変更を保存して終了
    q変更を保存せずに終了

    gdisk

    GPTに対応したパーティションのコマンドです。

    parted

    MBRにもGPTにも対応したコマンドです。

    check簡単なチェックを行う
    mklabel
    MBR形式 msdos
    GPT形式 gpt
    パーティションテーブルの作成
    mkpartパーティションの作成
    rm 番号パーティションの削除
    print pパーティションテーブルの表示
    quit q終了する

    ext2 Linux標準のファイルシステム

    ext3 ext2にジャーナリングシステムを追加

    ext4 ext3を機能拡張した

    XFS Red Hat Enterprise Linux 7やCentOS 7で標準のファイルシステム

    Btrfs

    B-tree file system

    Btrfsは、Linux向けの新しいファイルシステムです。

    • 複数の物理ボリュームにまたがりファイルシステムを作成できます(マルチデバイスファイルシステム)。
    • スナップショットを作成できます。
    • サブボリューム単位でのスナップショット機能があります。
    • ディレクトリの一部をサブボリュームとして個別のファイルシステムのように扱える

    /tmp

    「/tmp」ディレクトリは一時的なファイルを格納するディレクトリで、あらゆるユーザが書き込むことができます。また、格納されているファイルやディレクトリは再起動すると消去されます。

    mountコマンド

    マウントとはディスク装置をLinuxのディレクトリの配下に設定し使えるようにする作業をです。

    -a 全てのファイルシステムをマウント

    -t ファイルシステムのタイプを指定

    unmountコマンド

    My-Snow-Monkey使用例、子テーマによるカスタマイズ

    CSSファイルの読み込み

    My-Snow-Monkey プラグインをを有効化します

    FTPソフト等で下記の構成に

    wp-content/
    ├── plugins/
    │   └── my-snow-monkey/          # My Snow Monkeyプラグインのフォルダ
    │       ├── my-snow-monkey.php   # プラグインのメインファイル
    │       └── assets/
    │             └ style.css     # 読み込みたいcssファイル
    │
    └── themes/
        └── snow-monkey/            # Snow Monkeyテーマ本体

    my-snow-monkey.phpで下記コード記載(追記)

    // CSSファイルの読み込み
    add_action(
    	'wp_enqueue_scripts',
    	function() {
    		wp_enqueue_style(
                'my-snow-monkey',
    		 MY_SNOW_MONKEY_URL . '/assets/style.css', // my-snow-monkeyフォルダのassets/style.cssの場合
                [ Framework\Helper::get_main_style_handle() ],
                filemtime( MY_SNOW_MONKEY_PATH . '/assets/style.css' )
    		);
    	}
    );

    assets/style.css

    .l-header {
        background-color: #333;
        color: #fff;
    }

    下記のようにスタイルが反映されました

    wp_enqueue_scripts

    ユーザーが見るWebページにのみ出力されます。編集画面や管理画面には出力されません。

    enqueue列に加えるというような意味

    MY_SNOW_MONKEY_URL

     My Snow Monkeyで用意している定数。

    My Snow Monkey の URL… My Snow MonkeyのURL

    wp_enqueue_style()

    • WordPressではwp_enqueue_style()関数でファイルを読み込むことが推奨されています。
    • 基本的にフック(wp_enqueue_scripts等)を利用して読み込みます。
    wp_enqueue_style( $handle, $src, $deps, $ver, $media )
    
    $handle … スタイルのユニークな名前。
    $src … スタイルシートまでのURL
    $deps … 事前に読み込むべきスタイルの名前($handle)(配列形式)特に必要なければ、array()を記入(初期値はarray())
    $ver … 最新のバージョンを読み込ませる(初期値はfalse)
    $media … media属性 (初期値はall)

    https://happy-snow-monkey.olein-design.com/how-to-add-and-style-css-files-from-my-snow-monkey

    Snow MonkeyのブレイクポイントをCSSで書く場合

    
    @media screen and (max-width: 1279px) {
    // 1279px以下をここにかく
    }
    @media screen and (max-width: 1023px) { 
    // 1023px以下をここにかく
    }
    @media screen and (max-width: 639px) {
    // 639px以下をここにかく
    }

    jsファイルの読み込み

    my-snow-monkey.phpで下記コード記載

    add_action('wp_enqueue_scripts', 'msm_enqueue_style_script');
    function msm_enqueue_style_script()
    {
    	/* js読み込み */
    	wp_enqueue_script(
    		'msm_scripts',
    		MY_SNOW_MONKEY_URL . '/script.js', // my-snow-monkeyフォルダのscript.cssの場合
    		['jquery'],
    		filemtime(MY_SNOW_MONKEY_PATH . '/script.js'),
    		true // バージョン
    	);
    }

    wp_enqueue_script()

    wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer )
    
    $handle … スタイルのユニークな名前。
    $src … スタイルシートまでのURL
    $deps … 事前に読み込むべきスタイルの名前($handle)(配列形式)
    $ver … バージョン。falseにしておけばWordPressが自動的にバージョン情報を入れてくれます。初期値はfalse
        ※原因はわかりませんが、falseでなくてfilemtime( MY_SNOW_MONKEY_PATH . '/js/script.js' )を記載しないと動かない場合あり
    $in_footer … trueの場合</body>終了タグの前に配置される。 

    【注意点】$を参照する方法

    WordPressのjQueryを使う際、エラーを防ぐため下記のように変更する必要があります。

    // 方法1
    (function($) {
     // $()を使用可能
    })(jQuery);
    
    // 方法2
    jQuery(function( $ ) {
      〜
    } );
    https://snow-monkey.2inc.org/forums/topic/jquery%e3%82%92%e8%bf%bd%e8%a8%98%e3%81%97%e3%81%9f%e3%81%84%e3%81%a7%e3%81%99%e3%80%82

    head 要素内に独自のタグを追加

    FontAwesomeの読み込み

    // ------------------------------------------------
    // FontAwesomeの読み込み
    // ------------------------------------------------
    
    add_action('wp_head', function () {
     ?>
    
      <!-- FontAwesome -->
      <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
     <?php
    });

    下記の公式サイトのギャラリーページで使いたいアイコンのhtmlをコピーして使います。

    https://fontawesome.com/icons?d=gallery

    Googleマテリアルアイコン

    phone groups

    my-snow-monkey.phpを編集します

    // ------------------------------------------------
    // Googleマテリアルアイコン
    // ------------------------------------------------
    add_action('wp_head', function () {
    ?>
    //選択したアイコンのスタイルシート
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
    <?php
    });

    下記のGoogleマテリアルアイコンで使いたいアイコンのhtmlをコピーして使います。

    https://fonts.google.com/icons

    疑似要素で使用する場合

    my-snow-monkey.php

    // Googleマテリアルアイコン
    add_action('wp_head', function () {
    	?>
    	<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
    	<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    	<?php
    });
    .recruit-features li {
        min-width: 34%;
        padding-left: 60px;
        position: relative;
        font-size: 1.125rem;
        font-weight: bold;
    }
    
    .recruit-features li::before {
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        font-family: 'Material Icons';
        content: '\e92f';
        font-size: 2rem;
        line-height: 30px;
        width: 30px;
        height: 30px;
        background: var(--green2);
        border-radius: 50px;
    }

    文字の高さが合わないとき

    <a>会社概要
    <span class="material-symbols-outlined">chevron_right</span></a>

    このような場合は以下のようにcssを

    display: inline-flex;
    align-items: center;

    テンプレートのコメントアウト表示

    ワードプレスをインストールしたディレクトリ?にあるwp-config.phpに以下のコードを追記、もしくは書き換えすることで可能です。

    define( 'WP_DEBUG', true );
    
    ※ false → trueに

    何のテンプレートパーツを読み込んでいるのかをHTML内のコメントアウトで確認出来て便利です。

    テンプレートファイルの上書き

    viewディレクトリにSnow Monkeyはテンプレートファイルを格納しています。

    テンプレートを上書きするソースコード

    <?php
    add_filter(
    	'snow_monkey_template_part_root_hierarchy',
    	function( $hierarchy ) {
    		$hierarchy[] = untrailingslashit( __DIR__ ) . '/view';
    		return $hierarchy;
    	}
    );

    add_filter

    add_filter( フック名, 関数名, 優先順位, 引数の数 );

    【ページのコンテンツ部分にファイルを出力したい】※ヘッダー、フッターはそのまま使用

    テンプレートをmy-snow-monkey上に作成したファイル(※1)で上書きをし、特定のページIDの場合(※2)コンテンツ(html)をはく

    ※1子テーマの作成が不要

    手順(1)プラグインmy-snow-monkeyのfunctions.phpを編集

    // My Snow Monkey の中でテンプレートを追加できるようにする
    
    // 参考 https://snow-monkey.2inc.org/manual/manual-advanced/add-template-root/
    
    add_filter(
    	'snow_monkey_template_part_root_hierarchy',
    	function( $hierarchy ) {
    		$hierarchy[] = untrailingslashit( __DIR__ ) . '/override';
    		return $hierarchy;
    	}
    );

    手順(2)上書き対象のテンプレートファイルを調べる

    上記コメントアウト表示方法を参考

    例としてコンテンツを上書きしてみます。

    上書き前 snow-monkey/template-parts/content/entry/content/content.php

    上書き後 my-snow-monkey/override/template-parts/content/entry/content/content.php

    手順(3)上書きするのテンプレートファイルを作成

    上書き前のファイルを内容をコピペ

    例としてsnow-monkey/template-parts/content/entry/content/content.php

    ▼snow-monkey/template-parts/content/entry/content/content.php

    <?php
    /**
     * @package snow-monkey
     * @author inc2734
     * @license GPL-2.0+
     * @version 10.8.0
     */
    
    use Framework\Helper;
    ?>
    
    <?php do_action( 'snow_monkey_before_entry_content' ); ?>
    
    <div class="c-entry__content p-entry-content">
    	<?php do_action( 'snow_monkey_prepend_entry_content' ); ?>
    
    	<?php the_content(); ?>
    	<?php Helper::get_template_part( 'template-parts/content/link-pages' ); ?>
    
    	<?php do_action( 'snow_monkey_append_entry_content' ); ?>
    </div>
    
    <?php do_action( 'snow_monkey_after_entry_content' ); ?>
    

    ▼my-snow-monkey/override/template-parts/content/entry/content/content.php

    <?php
    /**
     * @package snow-monkey
     * @author inc2734
     * @license GPL-2.0+
     * @version 10.8.0
     */
    
    use Framework\Helper;
    ?>
    
    <?php do_action( 'snow_monkey_before_entry_content' ); ?>
    
    <div class="c-entry__content p-entry-content">
    	<?php do_action( 'snow_monkey_prepend_entry_content' ); ?>
    
        <?php
        if ( is_page('8') ) {
            ?>
                <p>my-snow-monkey/override/template-parts/content/entry/content/content.phpです。</p>
                <p>※ページID8の場合使用されます。</p>
            <?php
        }
        ?>
    
    	<?php Helper::get_template_part( 'template-parts/content/link-pages' ); ?>
    
    	<?php do_action( 'snow_monkey_append_entry_content' ); ?>
    </div>
    
    <?php do_action( 'snow_monkey_after_entry_content' ); ?>
    

    手順(複数のページの場合)さらにファイルを分割したほうがわかりやすい
    require ‘ファイル名’;で呼び出す

    my-snow-monkey/override/template-parts/content/entry/content/content.phpと同じディレクトリにrequireで呼び出すファイル用のディレクトリを作成します。(例:my-snow-monkey/override/template-parts/content/entry/content/require/id68.php)

    ▼my-snow-monkey/override/template-parts/content/entry/content/content.php

    <?php
    /**
     * @package snow-monkey
     * @author inc2734
     * @license GPL-2.0+
     * @version 10.8.0
     */
    
    use Framework\Helper;
    ?>
    
    <?php do_action( 'snow_monkey_before_entry_content' ); ?>
    
    <div class="c-entry__content p-entry-content">
    	<?php do_action( 'snow_monkey_prepend_entry_content' ); ?>
    
        <?php
        if ( is_page('68') ) {
            require 'require/id68.php';
        }
        ?>
    
        <?php
        if ( is_page('8') ) {
            require 'require/id8.php';
        }
        ?>
    
    	<?php Helper::get_template_part( 'template-parts/content/link-pages' ); ?>
    
    	<?php do_action( 'snow_monkey_append_entry_content' ); ?>
    </div>
    
    <?php do_action( 'snow_monkey_after_entry_content' ); ?>

    ▼my-snow-monkey/override/template-parts/content/entry/content/require/id68.php

    <p style="color: blueviolet">my-snow-monkey/override/template-parts/content/entry/content/require/id68.php</p>
    <p>※ページID68の場合使用されます。</p>です。

    https://snow-monkey.2inc.org/manual/manual-advanced/template-hooks

    https://snow-monkey.2inc.org/manual/manual-advanced/add-template-root

    https://happy-snow-monkey.olein-design.com/preparing-to-overwrite-the-snow-monkey-template-file-from-my-snow-monkey

    【ショートコード】編集画面で任意の場所にHTMLファイルを挿入

    https://bizlabo.site/?p=1228

    子テーマによるカスタマイズ

    • 子テーマによるカスタマイズは親テーマをバージョンアップしても、変更されません。
    • サイトの読み込み速度が遅くなる可能性があります。

    Snow Monkey の子テーマとして設定

    style.cssを編集する

    /**
     * Template: snow-monkey
     * Theme Name: Snow Monkey Child
     */
    
    親テーマ snow-monkeyの場合
    cssの読み込みの設定

    functions.phpを編集する

    CSSでスタイルを当てないカスタマイズの場合は不要?

    <?php
    add_action( 'wp_enqueue_scripts', function() {
    	wp_enqueue_style(
    		get_stylesheet(),          //子テーマの名前を取得
    		get_stylesheet_uri(),
    		[ get_template() ]         //現在有効中のテーマ
    	);
    } );
    wp_enqueue_style( $handle, $src, $deps, $ver, $media )
    
    $handle … スタイルのユニークな名前。
    $src … スタイルシートまでのURL
    $deps … 事前に読み込むべきスタイルの名前($handle)(配列形式)
    $ver … バージョン
    $media … media属性 
     body {
        background-color: #ccc;
      }

    エラー対応

    ブロック読み込みエラー 返答が正しい json レスポンスではありません。

    編集画面で下記表示になり更新できない

    「ブロック読み込みエラー 返答が正しい json レスポンスではありません。」

    解決方法

    解決方法を検索したところ、レンタルサーバのWAF設定、プラグイン由来等いろいろ原因は考えられるようですが、結論my-snow-monkeyプラグインのmy-snow-monkey.phpの記述でコメントアウトの仕方がおかしい箇所をなおしたら解決しました。

    参考:

    https://snow-monkey.2inc.org/forums/topic/%E8%BF%94%E7%AD%94%E3%81%8C%E6%AD%A3%E3%81%97%E3%81%84-json-%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%81%A7%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82
    Linuxのインストールと仮想マシン・コンテナの利用

    仮想マシン・コンテナの概念と利用

    コンテナ型仮想化とは

    サーバ仮想化技術のひとつです。

    コンテナ環境ではOS周辺の環境をゲストOSを使用せず、コンテナエンジンを共通で利用します。→処理が軽く、高速。使用容量が小さい

    コンテナ技術を管理するソフトウェア

    • Docker(基本的なソフトウェア)…Docker社が開発したコンテナ仮想化を用いてアプリケーションの開発や実行する環境を構築できるプラットフォーム
    • Kubernetesクバネティス…Googleが開発したコンテナ運用管理を支援するオープンソースのソフトウェア

    dockerコマンド

    docker run
    docker start
    docker stop
    docker kill
    docker ps
    docker rm
    docker attachコンテナの標準入出力に接続
    docker exec
    docker pullDocker Hubからダウンロード
    docker pushDocker Hubにアップロード
    docker imagesイメージ一覧表示

    ブートプロセスとsystemd

    1. 電源投入
    2. ファームウェア(BIOS、UEFI)動作…マザーボード上のNVRAM(不揮発性メモリ)
      • ブートローダを呼び出す…現在GRUB2がよく使用される
      • 優先順位に従って各デバイスの先頭セクタのMBRを読み込む
    3. ブートローダ
      • kernel(Linuxの基本システム)とRAMディスク
      • ブートローダは起動されると、記憶装置(HDD)内のカーネルをロードし、制御を移します。
    4. カーネルを起動
      • メモリ初期化やハードウェア認識
    5. systemd、initでサービス(sshd、httpd、mysqld)起動
      • init:SysVinit(Sustem Five Init)将来
      • systemd:現在のLinuxで採用
    6. ログインプロンプト表示

    UEFI

    Unified Extensible Firmware Interface

    IntelがBIOSにかわるインターフェイスとして考案したのが、UEFIです。

    • GUIでの操作をサポート
    • 3TBを超える大容量HDDからの起動をサポート

    systemd

    サービスを並列に起動することにより、起動が高速

    Unit(処理単位)

    • systemctlで制御
    • 以下のタイプがあります
      • service(各種サービス起動)httpd、sshd等
      • device(デバイス)
      • mount(ファイルシステム)/etc/fstab
      • swap(スワップ領域の有効化。ディスクをメモリに)
      • target(複数Unitをグループ化)

    ターゲット

    ターゲット
    (systemd)
    ランレベル
    (init)
    default.targetシステム起動時のデフォルトのターゲット
    sysinit.targetシステム起動時の初期段階のセットアップを行う
    poweroff.target0システム終了
    rescue.target1レスキュー(シングルユーザー)モード
    multi-user.target2,3,4CUIログイン
    graphical.target5グラフィカルログイン
    reboot.target6システム再起動

    systemctl

    systemdが稼働するシステムの各サービスの管理はsystemctlコマンドを使用します。

    systemctl サブコマンド Unit名

    enable自動起動を有効
    get-default次回起動時のターゲットを表示
    set-default次回起動時のターゲットを設定
    haltシステムを停止しhalt状態にする(停止)
    poweroffシステムを停止し電源を切断
    startサービスを起動
    stopサービスを停止
    restartサービスを再起動
    is-activeサービスが稼働しているかを表示
    isolateほかのUnitを停止し、対象のUnitを起動
    rebootシステムを再起動

    シャットダウン、再起動

    シャットダウンや再起動は、systemctrコマンド以外にshutdownコマンドを使う方法があります。

    shutdown [オプション] 時間 [メッセージ]
    -hシャットダウンする
    -rシャットダウン後再起動する
    -f次回起動時にfsckをスキップする
    -h、-rと併用する
    -F次回起動時にfsckを実行する
    -h、-rと併用する
    -kシャットダウンせずに警告メッセージを通知
    -cシャットダウンをキャンセルする

    ssh

    公開鍵認証 … 秘密鍵で暗号化→公開鍵で復号化(上記認証)

    公開鍵暗号 … 公開鍵で暗号化→秘密鍵で復号化

    プロセスの生成、監視、終了

    プロセスという基本単位でOSは動作中のプログラムを管理します。

    psコマンド

    process status

    psコマンドは現在実行中のプロセスを表示するときに使います。

    aほかのユーザのプロセスも表示
    f親子関係をツリー上で表示
    uユーザ名を表示
    xデーモン等表示
    -eすべてのプロセスを表示
    -f完全なフォーマットでプロセスを表示
    -l詳細情報を表示
    -p PID指定のPIDの情報を表示
    -C プロセス名指定の名前の情報を表示
    -w長い行は折返し

    topコマンド

    実行中のプロセスを継続的に監視するときに使用します。

    killコマンド

    killコマンドはプロセスにシグナルを送ります。プロセスはシグナルを受け取るとそれに応じた、動作を実行します。

    シグナル名シグナルID動作
    HUP1ハングアップ(端末が制御不能)
    INT2キーボードからの割り込み(Ctrl + Cキー)
    KILL9強制終了
    TERM15終了(デフォルト)
    CONT18停止しているプロセスを再開
    STOP19一時停止
    TSTP20端末から一時停止(Ctrl + Zキー)

    killallコマンド

    指定したコマンドを実行している全てのプロセスに対してシグナルを送します。

    killall [-シグナル名、-シグナル番号] プロセス名(コマンド名)

    pgrepコマンド

    指定のプロセスのPIDを表示します。

    -U、–uid ユーザ名実行ユーザーを指定
    -G、–group グループ名実行グループを指定
    -n、–newestもっとも新しいプロセスを選択
    -o、–oldestもっとも古いプロセスを選択
    -l、–list-nameプロセス名も表示

    フォアグラウンドとバックグラウンド

    bg

    フォアグラウンドで実行中のジョブをバックグラウンドで実行する

    fg

    バックグラウンドで実行中のジョブをフォアグラウンドで実行する

    端末の活用

    tmux、screen

    複数の画面で切り替えて作業を行えるソフトウェアです。

    デスクトップ環境の利用

    LinuxはGUIを実現する機能はそなわっていないです。

    そこで、GUIをじつげんするためのシステムとしてX Window Systemが使われてきました。

    X Window System

    XサーバとXクライアントから構成されています。

    ウィンドウマネージャ

    X Window Systemの外観を制御しているのがウィンドウマネージャです。

    twmは最小限の機能を備えたウィンドウマネージャです。

    GUIの起動

    startxコマンドでX Window Systemが起動します。(CUI環境‥ランレベル3)

    ディスプレイマネージャ

    • ランレベル5で起動すると、ディスプレイマネージャはXサーバを起動し、GUIのログイン画面を表示させます。
    • initやsystemdによりディスプレイマネージャーサービスが起動されます。

    xauth

    xauthコマンドはXサーバの接続で使われる資格情報を表示したり、クライアント認証ファイルを編集するときに使います。

    • xauth listコマンドでXサーバごとの接続に使用される資格情報が表示されます。(Xサーバ側)
    • xauthのaddコマンドで、ユーザの~/.Xauthorityファイル(クライアント認証ファイル)にXサーバと同じ資格情報を保存し、Xサーバと資格情報が一致したユーザのみがアクセスできるようになります。(Xクライアント側)
    ファイル・ディレクトリの操作と管理

    ファイルの所有者とパーミッション

    アクセス権

    読み取りr
    書き込みw
    実行権x
    権限ファイルの適用ディレクトリに適用
    読み内容を参照内容を参照
    書き書き込みファイルの新規作成、削除、名前変更
    実行ファイルを実行ディレクトリのファイルにアクセス、ディレクトリへの移動

    アクセス権の表記法

    所有者グループその他ユーザ
    記号表記:r w xr – xr – –
    4 2 14 – 14 – –
    数値表記:754

    chmod

    「change mode」

    chmod [ オプション ] アクセス権 ファイル名
    オプション … -R --recursive 指定した以下にある全ファイルのアクセス権を変更
    オプション内容
    -R –r指定したディレクトリのファイル全てのアクセス権を変更する
    対象内容
    u所有者
    gグループ
    oその他
    a全ユーザ
    種別内容
    r読み取り
    w書込み
    x実行
    sSUID、SGID
    tスティッキービット

    SUID、SGID

    「Set User ID」、「Set Group ID」

    SUID、SGIDは特殊なアクセス権です。

    そのファイルを誰が実行しても所有者の権限・グループの権限で実行されることを意味します

    SUIDを設定するには、

    • chmod 4755 file(3桁のアクセス権に4000を加える)
    • chmod u+s file(所有者に「s」という権限を追加します)

    SGIDを設定するには、

    • chmod 2755 file(3桁のアクセス権に2000を加える)
    • chmod g+s file(グループに「s」という権限を追加します)

    スティッキービット

    自分以外の他のユーザが所有しているファイルを削除出来ないようにするには、スティッキービットをディレクトリに設定します。

    • 通常のパーミッションの値に1000を加えた値を設定する
    • その他ユーザに「t」という権限を追加する

    umask

    ファイルやディレクトリ作成時のデフォルトのアクセス権は、umask値で決まります。

    • ファイル … 666 – umask値
    • ディレクトリ … 777 – umask値

    http://www.rivhiro-weather.com/knowledge/?p=168

    chown

    chown [ オプション ] ユーザ ファイル名/ディレクトリ名
    chown [ オプション ] :グループ名 ファイル名/ディレクトリ名
    オプション … -R --recursive 指定した以下にある全ファイルの所有者を変更

    chgrp

    chgrp [ オプション ] グループ ファイル名/ディレクトリ名
    オプション … -R --recursive 指定した以下にある全ファイルの所有者を変更

    ハードリンクとシンボリックリンク

    ファイルの実体に名前を結びつける「ハードリンク」と、 名前に名前を結びつける「シンボリックリンク」の2つがあります。

    iノード番号

    Linuxではファイルを保存するとユニークな値でiノード番号が割り当てられます。

    iノードにはファイルに関する属性情報が格納されています。

    ハードリンク

    • iノード番号が同じ
    • ハードリンクが0になると、実体がはじめて削除されます
    • ファイルシステムが異なると作成できない
      です
    • ディレクトリのハードリンクは作成できません

    シンボリックリンク

    • 別ファイルシステムへのリンク作成が可能
    • lsコマンドで確認するとパーミッションの先頭に「l」が表示される

    ln

    リンクの作成にはlnコマンドを利用します。

    ln [-s‥シンボリックリンク] リンク元 リンク先

    • ハードリンクは異なるファイルシステムに作成できません。
    • ディレクトリのハードリンクは作成できません。

    基本的なファイル管理の実行

    pwd

    カレントディレクトリを表示する

    「print working directory(作業ディレクトリを表示する)」

    ls コマンド

    「list」の略

    カレントディレクトリのファイル一覧を表示します。

    ls [オプション] [ファイル名、ディレクトリ名]

    -a(all)all、ドット(隠し)ファイルも表示
    -d(dir)ディレクトリの情報を表示
    -Rサブディレクトリの内容も表示
    -l(long)詳細情報を表示
    -h(MB、KB)メガバイト、キロバイトの単位で情報を表示
    -i(i-node)i-nodeの情報を表示

    cd

    カレントディレクトリをホームディレクトリに変更する

    change directory

    ホームディレクトリへのパス
    cd
    cd ~(チルダ展開)
    ひとつ前に戻る
    cd -

    cp コマンド

    fコピー先の既存のファイルやディレクトリが上書き出ない場合、削除してからコピーする
    r、Rディレクトリを再起的にコピー
    i同名のものがある場合、上書きするか問い合わせる
    pファイルの属性を保持したままコピー

    mv コマンド

    ファイルやディレクトリを移動するときや名前を変えるときに使うコマンド

    -f –force移動先に同名のファイルやディレクトリがある場合、上書きする
    -i –interactive移動先に同名のファイルやディレクトリがある場合、上書きするか問い合わせる

    mkdir コマンド

    ディレクトリを作成するにはmkdirコマンドを利用します

    -m –mode 指定したアクセス権でディレクトリを作成
    -p –parents必要な場合親ディレクトリを作成する

    rm コマンド

    ファイルやディレクトリを削除できるコマンド。

    -f –forceユーザへの確認なしで削除する
    -i削除前にユーザに確認する
    -r、-R –recursiveサブディレクトリを含めディレクトリ全体を再帰的に削除する

    rmdir コマンド

    空のディレクトリのみ削除できる

    d ディレクトリ名に階層を指定した場合、削除するディレクトリの親ディレクトリを同時に削除するオプションです。

    p 複数階層の空ディレクトリを削除する

    ※(区別)rm -r空ではないディレクトリも削除することができる

    touch コマンド

    • ファイルのタイムスタンプを更新します
      • すでにあるファイルのタイムスタンプだけ更新する
      • touch -t MMDDHH mm filename
    • 空のファイルを生成します(本来はタイムスタンプを変更するコマンドでしたが、指定したファイルがない場合は新規作成する)
    tアクセス時刻と修正時刻を指定した時刻に変更
    aアクセス時刻を変更
    m修正時刻を変更

    gzip

    gzip形式でファイルを圧縮するにはgzipコマンドを利用します。

    元ファイルを残して標準出力に出力

    -d –decompress圧縮ファイルを展開
    -c –stdout標準出力へ出力
    -k –keep圧縮、解凍後に元ファイルを削除しない
    -r –recutsiveディレクトリ内の全ファイルを圧縮

    gunzip

    gunzipコマンドで展開できます。

    bzip2

    -d –decompress圧縮ファイルを展開
    -c –stdout元ファイルを残して標準出力
    -k –keep圧縮、解凍後に元ファイルを削除しない

    bzip2 [オプション] [ファイル名]

    xz

    xz [オプション] [ファイル名]

    -d –decompress圧縮ファイルの展開
    -k –keep圧縮、展開後ファイルを削除しない
    -l –list圧縮ファイルの情報を表示する

    xz -dコマンドの代わりにunxzコマンドを使ってもかまいません。

    tar

    tape archive

    複数のファイルをまとめて一つのアーカイブにしたり、アーカイブを展開するときに使うコマンド。

    [作成するファイル名][圧縮するディレクトリ名]

    c createアーカイブを作成
    x extractアーカイブからファイルを展開
    t listアーカイブの内容一覧を表示
    f filenameアーカイブファイル名を指定
    z gzipgzipを通して、圧縮/展開
    j bzip2bzip2を通して、圧縮/展開
    J xzxzを通して、圧縮/展開
    v verbose処理の詳細を表示

    dd

    ブロックサイズとコピー回数を指定してファイルを作成できるコマンド。

    if=入力ファイル入力ファイルを指定
    of=出力ファイル出力ファイルを指定
    bs= バイト数作成するファイルのブロックサイズを指定
    count=回数回数分の入力ブロックをコピー

    ファイルの配置と検索

    FHS

    Filesystem Hierarchy Standard

    Linuxの標準的なディレクトリレイアウトを定めた標準かされている仕様

    FHSさえ知っていればソフトウェア固有の知識のインプットをを最小限にすることができます。

    /dev

    デバイスファイルを入れるディレクトリ

    /usr/bin

    ユーザが一般的に使うコマンドがあります。システムの起動や、緊急時の保守には必須でないものです。

    /etc

    設定ファイルを入れるディレクトリ

    /home

    ホームディレクトリを入れるディレクトリ

    ユーザが自由に操作できるユーザー名のディレクトリがあります。

    man hier

    HIER(7)			   Linux Programmer’s Manual		       HIER(7)
    名前
           hier - ファイルシステム階層の説明
    説明
           典 型的な Linux system には以下のようなディレクトリがある (他にもたくさ
           んのディレクトリがあるが):
           /      ルートディレクトリ。ここが階層の起点となる。
           /bin   このディレクトリには、シングルユーザーモードでシステムの起動や修
    	      理を行う際に必要な実行形式ファイルが含まれる。
           /boot  ブートローダが用いる静的なファイルが含まれている。このディレクト
    	      リにはブートプロセスの間に必要なファイルだけが置かれる。マップイ
    	      ンストーラや設定ファイルは /sbin や /etc に置くべきである。
           /dev   物理デバイスを参照しているスペシャルファイルやデバイスファイルの
    	      置き場所。 mknod(1) を参照のこと。
           /etc   マシン固有の設定ファイルが置かれる場所。X11 のような大規模なソフ
    	      トウェアパッケージでは、 /etc 以下に更にパッケージ単位でサブディ
    	      レクトリが作られることもある。サイト全体に有効な設定ファイルは、
    	      ここではなく /usr/etc に置かれることもある。しかし、プログラムか
    	      らのこれらのファイルの参照先は、常に /etc にす べ き で あ る 。
    	      /usr/etc	以下のファイルに対しては、それらへのリンクを /etc に置
    	      けばよい。
           /etc/opt
    	      /opt にインストールされたアドオンアプリケーションが使う、ホス ト
    	      固有の設定ファイルの置き場所。
           /etc/sgml
    	      SGML や XML の設定ファイルの置き場所 (なくてもよい)。
           /etc/skel
    	      新たにユーザーアカウントを作る際、通常このディレクトリにあるファ
    	      イルがユーザーのホームディレクトリにコピーされる。
           /etc/X11
    	      X11 window system の設定ファイルの置き場所 (なくてもよい)。
           /home  通常、ユーザーのホームディレクトリが、このディレクトリ直下ないし
    	      サブディレクトリの下に作成される。このディレクトリの構成をどうす
    	      るかは、ローカルマシンの管理者が決めることである。
           /lib   このディレクトリには、システムの起動時に必要な共有ライブラリや、
    	      ルートファイルシステムでコマンドを実行するのに必要な共有ライブラ
    	      リを置く。
           /media このディレクトリには、 CD/DVD ディスクや USB スティックなどの 取
    	      り 外し可能メディア (removable media) 用のマウントポイントが置か
    	      れる。
           /mnt   このディレクトリは、一時的にマウントするファイルシステム用のマウ
    	      ントポイントである。ディストリビューションによっては、一時的にマ
    	      ウントするファイルシステム用のマウントポイントとして、 /mnt 内に
    	      サブディレクトリが用意されている場合がある。
           /opt   このディレクトリにはアドオンパッケージの静的なファイルが置かれる
    	      。
           /proc  このディレクトリは proc ファイルシステムのマウントポイントである
    	      。 proc ファイルシステムは、実行中プロセスやカーネルの情報を提供
    	      する。この疑似ファイルシステムの詳細は、 proc(5) で説明されて い
    	      る。
           /root   通常ここが root ユーザのホームディレクトリになる (なくてもよい)
    	      。
           /sbin  /bin と同様に、このディレクトリにはシステムの起動に必要なコマ ン
    	      ドが含まれる。ただしここには、一般ユーザーは通常実行しないコマン
    	      ドが置かれる。
           /tmp   このディレクトリには、定期的なジョブによって、またはシステム起動
    	      時に、無条件に削除して構わない一時的なファイルが置かれる。
           /usr   通常このディレクトリは、独立したパーティションがマウントされる。
    	      ここには、共有可能で読み込み専用のものだけが含まれ、よっていろい
    	      ろな Linux マシンからマウントできる。
           /usr/X11R6
    	      X Window System, Version 11 release 6 (なくてもよい)。
           /usr/X11R6/bin
    	      X	 Window	 System	  のバイナリの置き場所。古いディレクトリである
    	      /usr/bin/X11 からここにシンボリックリンクが張られていることが 多
    	      い。
           /usr/X11R6/lib
    	      X Window System に関連するデータファイルの置き場所。
           /usr/X11R6/lib/X11
    	      こ こ に は  X   の 動 作 に必要な種々のファイルが含まれている。
    	      /usr/lib/X11 からここにシンボリックリンクが張られていることが 多
    	      い。
           /usr/X11R6/include/X11
    	      こ こには X11 Window System を使ったプログラムをコンパイルするた
    	      めに必要なインクルードファイルが含まれている。  /usr/include/X11
    	      からここにシンボリックリンクが張られていることが多い。
           /usr/bin
    	      このディレクトリは、実行形式ファイルの主な置き場所である。システ
    	      ムのブートやシステム復旧には必要とされない、一般ユーザーが利用す
    	      るコマンドの多くは、ローカルにインストールされるのでない限り、こ
    	      のディレクトリに置くべきである。
           /usr/bin/X11
    	      X11 コマンドの伝統的な置き場所。Linux では、通常	/usr/X11R6/bin
    	      にシンボリックリンクが張られている。
           /usr/dict
    	      /usr/share/dict に置き換えられた。
           /usr/doc
    	      /usr/share/doc に置き換えられた。
           /usr/etc
    	      サイト内部の複数のマシンが共有するような設定ファイルが置かれる。
    	      しかしながら、コマンドはそれらのファイルの参照先を、常に /etc に
    	      すべきだろう。 /etc のファイルからリンクを張って、 /usr/etc の適
    	      切なファイルを指すようにすべきである。
           /usr/games
    	      ゲームプログラムや教育用プログラムのバイナリが含まれている (なく
    	      てもよい)。
           /usr/include
    	      C コンパイラ用のインクルードファイルが含まれている。
           /usr/include/X11
    	      C	 コンパイラと X Window System 用のインクルードファイルが含まれ
    	      ている。通常これは /usr/inlcude/X11 へのシンボリックリンクになっ
    	      ている。
           /usr/include/asm
    	      アセンブラ関数の宣言を行うインクルードファイルが含まれている。こ
    	      のディレクトリは、以前は /usr/src/linux/include/asm へのシンボリ
    	      ックリンクだった。
           /usr/include/linux
    	      ここには、システムのリリースのたびごとに変更されうる情報が含まれ
    	      る。ここは以前は /usr/src/linux/include/linux にシンボリックリン
    	      クされており、オペレーティングシステム固有の情報が得られるように
    	      なっていた。
    	      (ここに置くインクルードファイルは、現在の libc およびユーザ空 間
    	      で 正しく動作するものでなければならない。しかし Linux のカーネル
    	      ソースはユーザプログラムといっしょに使うようには設計されていない
    	      し 、 あなたが使っている libc も関知しない。 /usr/include/asm と
    	      /usr/include/linux を適当なカーネルツリーへのリンクにしたりす る
    	      と 、 破 綻 す る の は 目 に 見えている。 Debian ではこうせずに
    	      、libc*-dev package が提供する、安定したカーネルバージョンのヘッ
    	      ダファイルを置いている。)
           /usr/include/g++
    	      GNU C++ コンパイラ用のインクルードファイルが含まれている。
           /usr/lib
    	      オブジェクトライブラリ (ダイナミックライブラリも含む) と、直接に
    	      は起動されないような実行形式ファイル少々とが置かれる。複雑なプロ
    	      グラムでは、更にサブディレクトリがあるかもしれない。
           /usr/lib/X11
    	      X	 のプログラムに関連するデータファイルと、 X Window System の設
    	      定ファイルの置き場所。 Linux では通常 /usr/X11R6/lib/X11 にシ ン
    	      ボリックリンクが張られている。
           /usr/lib/gcc-lib
    	      GNU C コンパイラ gcc(1) 用の実行形式ファイルとインクルードファイ
    	      ルが含まれている。
           /usr/lib/groff
    	      GNU groff 文書整形システムのためのファイルが含まれている。
           /usr/lib/uucp
    	      uucp(1) のためのファイルが含まれている。
           /usr/local
    	      このディレクトリは、サイトローカルなプログラムがインストールされ
    	      る典型的な場所である。
           /usr/local/bin
    	      サイトローカルなプログラムが含まれている。
           /usr/local/doc
    	      サイトローカルなドキュメントが含まれている。
           /usr/local/etc
    	      サイトローカルにインストールされたプログラムの設定ファイルの置き
    	      場所。
           /usr/local/games
    	      サイトローカルにインストールされたゲームのバイナリの置き場所。
           /usr/local/lib
    	      サイトローカルにインストールされたプログラムの関連ファイルの置き
    	      場所。
           /usr/local/include
    	      ローカルな C コンパイラのヘッダファイルの置き場所。
           /usr/local/info
    	      サイトローカルにインストールされたプログラムの info ページの置き
    	      場所。
           /usr/local/man
    	      サイトローカルにインストールされたプログラムのマニュアルページの
    	      置き場所。
           /usr/local/sbin
    	      サイトローカルにインストールされたシステム管理コマンドの置き場所
    	      。
           /usr/local/share
    	      同じ OS ならアーキテクチャが異なっても共有できる、ローカルなアプ
    	      リケーションデータの置き場所。
           /usr/local/src
    	      サイトローカルにインストールされたソフトウェアのソースコードの置
    	      き場所。
           /usr/man
    	      /usr/share/man に置き換えられた。
           /usr/sbin
    	      このディレクトリには、システム管理コマンドが含まれる。ここに置か
    	      れるコマンドは、ブートプロセスや /usr のマウント、システムの修理
    	      などに必要なものであってはならない。
           /usr/share
    	      このディレクトリには、アプリケーションごとに固有なデータ ( 同 じ
    	      OS  ならアーキテクチャが違っていても共有できるもの) がサブディレ
    	      クトリ単位で置かれる。以前には /usr/doc, /usr/lib, /usr/man など
    	      にあった内容が、多くここに置かれている。
           /usr/share/dict
    	      スペルチェッカ用の単語リストが含まれる。
           /usr/share/doc
    	      インストールされたプログラムのドキュメントの置き場所。
           /usr/share/games
    	      /usr/games に置かれたゲーム用の静的なデータファイルの置き場所。
           /usr/share/info
    	      info ページが置かれる。
           /usr/share/locale
    	      ロケール (locale) 情報が置かれる。
           /usr/share/man
    	      マニュアルページ。各ページはセクションに応じたサブディレクトリに
    	      置かれる。
           /usr/share/man//man[1-9]
    	      これらのディレクトリには、各ロケールのマニュアルページのソースが
    	      置かれている。すべてのマニュアルページで同じ言語とコードセットを
    	      使用するシステムでは、  は省略されることがある。
           /usr/share/misc
    	      同じ OS ならアーキテクチャが違っていても共有できる、雑多なデータ
    	      の置き場所。
           /usr/share/nls
    	      母 国語サポート (native language support) 用のメッセージカタログ
    	      の置き場所。
           /usr/share/sgml
    	      SGML や XML のファイルの置き場所。
           /usr/share/terminfo
    	      terminfo のデータベースが置かれる。
           /usr/share/tmac
    	      groff と一緒には配布されていない troff マクロの置き場所。
           /usr/share/zoneinfo
    	      タイムゾーン情報のファイルが置かれる。
           /usr/src
    	      システム上の色々なコンポーネントのソースファイル (参照用のパッケ
    	      ージも含む) の置き場所。この場所で自分のプロジェクトの作業をして
    	      はいけない。 /usr 以下のファイルはソフトウェアのインストールの時
    	      以外は読み込み専用になっているべきだからである。
           /usr/src/linux
    	      かつてはカーネルソースの伝統的な置き場所だった。ディストリビュー
    	      ションによっては、出荷時のデフォルトのカーネルのソースをここに置
    	      いている。自分でカーネルをビルドするときは別の場所を使うほうがい
    	      いだろう。
           /usr/tmp
    	      今では用いられなくなった。このディレクトリは /var/tmp へのリンク
    	      にすべきである。このリンクは互換性のためだけにあり、もはや使うべ
    	      きでない。
           /var   このディレクトリには、スプールファイルやログファイルのような、サ
    	      イズが変化するファイルが置かれる。
           /var/adm
    	      このディレクトリは /var/log に置き換えられた。ここは /var/log へ
    	      のシンボリックリンクにすべきである。
           /var/backups
    	      歴史的な理由からまだ残っている。
           /var/cache
    	      プログラムのためにキャッシュされたデータの置き場所。
           /var/catman/cat[1-9] or /var/cache/man/cat[1-9]
    	      これらのディレクトリには、整形済みのマニュアルページが、ページの
    	      セクションに従って置かれている。 (整形済みマニュアルページの利用
    	      は推奨されていない。)
           /var/cron
    	      歴史的な理由からまだ残っている。
           /var/lib
    	      プログラムの状態に関する情報のうち、可変なものの置き場所。
           /var/local
    	      /usr/local 用の可変データの置き場所。
           /var/lock
    	      ロックファイルの置き場所。デバイスのロックファイルの命名は、慣習
    	      と して LCK.. とされている。ここで  はファイルシ
    	      ステム上でのデバイス名である。利用されているフォーマット は  HDU
    	      UUCP  のロックファイルのものである。すなわち各ロックファイルには
    	      アスキー 10 進数値文字で表記した PID 10 バイトと、それに続いて改
    	      行文字とが含まれている。
           /var/log
    	      種々のログファイルの置き場所。
           /var/opt
    	      /opt 用の可変データの置き場所。
           /var/mail
    	      ユ ーザのメールボックスの置き場所。 /var/spool/mail を置き換えた
    	      。
           /var/msgs
    	      歴史的な理由からまだ残っている。
           /var/preserve
    	      歴史的な理由からまだ残っている。
           /var/run
    	      実行時の可変ファイルが置かれる。例えばプロセス識別子 (PID) を 保
    	      持するファイルや、ユーザのログイン情報ファイル (utmp) などである
    	      。ここのファイルは、通常システム起動時に削除される。
           /var/spool
    	      色々なプログラムのスプールファイル (あるいはキューファイル) の置
    	      き場所。
           /var/spool/at
    	      at(1) のジョブスプール。
           /var/spool/cron
    	      cron(8) のジョブスプール。
           /var/spool/lpd
    	      印刷用のスプールファイルが置かれる。
           /var/spool/mail
    	      /var/mail に置き換えられた。
           /var/spool/mqueue
    	      キューイングされた送信メールの置き場所。
           /var/spool/news
    	      ニュースのスプールディレクトリ。
           /var/spool/rwho
    	      rwhod(8) のスプールファイルの置き場所。
           /var/spool/smail
    	      メール配送プログラム smail(1) のスプールファイルの置き場所。
           /var/spool/uucp
    	      uucp(1) のスプールファイルの置き場所。
           /var/tmp
    	      /tmp  と似ているが、このディレクトリに置かれる一時的なファイルは
    	      保存期間の制限がない。
           /var/yp
    	      NIS のデータベースファイルの置き場所。
    準拠
           The  Filesystem	Hierarchy  Standard,  Version  2.2   .
    バグ
           こ のリストは網羅的なものではない。個々のシステムでは異なる部分があるか
           もしれない。
    関連項目
           find(1), ln(1), proc(5), mount(8)
           The Filesystem Hierarchy Standard
    Linux				  2001-09-07			       HIER(7)

    locateコマンド

    検索用データベースで高速にファイル名ディレクトリ名の検索を行います。

    updatedbコマンド

    locateコマンドが利用する検索用のデータベースを更新します。

    findコマンドし

    指定ディレクトリからファイル、ディレクトリを検索します。

    find [検索起点ディレクトリ] [検索式] [アクション]

    whichコマンド

    環境変数PATHに基づき検索します。

    whereisコマンド

    指定コマンドのバイナリーファイル、ソースコード、マニュアルファイルの場所を検索します。

    typeコマンド

    【Linux技術者認定試験】LinuC

    LinuCとは

    「Linux技術者認定試験LinuC」

    LPI-Japanが運営しているLinuxの試験です。

    同じLinux資格にLpicがあります、いくつか違いがあります。

    LinuCLpic
    コンテナ技術やクラウド技術が含まれる
    →クラウド時代にあった資格
    含まれていない
    日本独自の試験世界中で実施されている試験

    試験概要

    試験時間各試験90分
    出題数各試験60問
    出題形式CBT方式(コンピュータ試験)
    受験料
    (税込、1科目あたり)
    LinuC-1:16500円
    LinuC-2:16500円
    LinuC-3:16500円

    試験範囲

    101試験

    • Linuxのインストールと仮想マシン・コンテナの利用
    • ファイル・ディレクトリの操作と管理
    • GNUとUnixのコマンド
    • リポジトリとパッケージ管理
    • ハードウェア、ディスク、パーティション、ファイルシステム

    102試験

    • シェルおよびスクリプト
    • ネットワークの基礎
    • システム管理
    • 重要なシステムサービス
    • セキュリティ
    • オープンソースの文化

    おすすめ学習方法

    • あずき本
    • Ping-t
    • スピードマスター問題集

    暗記が重要になるので実際コマンド入力、アウトプットが重要になると思います。

    学習時間

    LinuCレベル1の学習時間は平均的に3ヶ月間

    LinuC Lv1-101(Ver10.0)合格者の声

    680 点 1.5か月 最初の1か月であずき本を読みつつ、単元ごとに未出題をなくすようにping-tの練習問題を解く。 あずき本からダウンロードできる環境で実際にコマンドを打って勉強しました。 残りの2週間でミス、ヒットを消し、模試は3日前から手を付けました。コマ問は触っていないです。

    680 点 3週間 1, 上記テキストを一章読む 2, 該当セクションの問題をping-tで解きまくる 3, 全ての章で1と2を繰り返す 4, ping-tの模試を9割取れるまでやりまくる 5, コマ問を7割取れるまでやる(ここで試験日に到達)

    626 点 2カ月 Ping-tをダラダラやっていただけで自信が無かったが、想像以上に当日試験が簡単だった。 難易度としてはPing-tの問題と大差ないもしくはそれ以下。 480点で合格のようで、もっと早く受験すればよかったと思う。 問題文も1~2行くらいで時間も大量に余った。 公式の重要度でどの分野が何問ずつ出るのか確認しておくと、直前の復習がしやすくていいかもしれない。 自信がなくてもさっさと受けることをおすすめする。

    613 点 1ヶ月 Pint-Tの最強問題集をやるだけ。 だらだら勉強してたので1ヶ月かかりました。 学習履歴を振り返ってみたところ、1週間しかまともに勉強してなかったです。 ダラダラと勉強してしまう癖を直さないとなので、2週間後に102も受験します。

    560 点 1ヶ月 pingtは模擬で90%以上が安定して取れるようひたすらやりこむ。その後に白本を2週ぐらいコマ問はほぼやってない

    480 点 5ヶ月 最初にスピードマスター問題集を3周ほどしてから、Ping-tをやり始めました。  1度目は不合格で、未出題の問題がたくさんあったので、2回目の受験準備の際は、とにかく問題を解きまくりました。 未出題がなくなったら、模擬試験→ミスした問題をもう一度という感じで覚えていきました。

    706 点 2週間 小豆本を読んだ後、ping-tとスピードマスター問題集で全部正解まで繰り返す ping-tのコマンドは面倒なのでやりませんでした。 試験の感想 ping-tと類似の問題が多く、安心して受験できました。 コマンド入力問題は7個、複数選択問題は8個でした。 コマンド入力問題はコマンドだけ・オプションだけの問題だったので簡単でした。

    600 点 24日 解説ではカラフルな図も多く、スピードマスターより遥かにわかりやすいと思います。 Ping-Tの問題レベルは少し簡単でスピードマスターの問題のほうが本番レベルに近いと思う。 Ping-Tだけでも合格できるかもしれませんが、Ping-Tを仕上げればスピードマスターは数日で回せるでしょう。 Ping-T、スピードマスターともレベル1の本番試験には役立ちました。 面白いことにスピードマスター模試の得点率67%と今回の600点 (おそらく本番のテスト400/600満点)の67%が同じだった。

    jQuery

    jQueryとは

    JavaScriptのためのライブラリです。

    JavaScriptの長い記述を短く書くことができ、複雑なJavaScriptを簡単に使うことができます。

    jQueryでできること

    • HTML、CSSの操作
    • 表示、非表示
    • アニメーション

    jQueryのデメリット

    • jQueryの読み込みによる遅延
    • 古いもので、現在対応しておらず、動作しないものがある

    CDNによる読み込み

    公式サイト

    • 最新バージョンである3系で
    • 特に理由がなければminified

    https://releases.jquery.com
    • jQueryを読み込む場所はheadタグ内、もしくはbody閉じタグ直前で読み込み
      ブラウザの表示を遅らせないためにbody閉じタグ直前が無難です。
    • 自作のjsファイルよりも先に読み込む
      • <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
        <script src="my-script.js"></script>

    Google CDN

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>

    https://developers.google.com/speed/libraries?hl=ja#jquery

    自作のjsファイルの記述

    $(function () {
     // jqueryの処理を記述 
    });
    ※上記は省略形で下記の記述が省略しない場合
    jQuery(document).ready(function(){ //HTMLの読み込み後、記述した処理の開始を意味しています
      // jqueryの処理を記述
    });

    jQueryイベントのバブリングとは?

    バブリングとは、イベントが発生した要素の親要素、祖先要素にも同様のイベントが発生することです。

    バブリングの挙動を理解したうえで、jQueryを使用しないと予想外の問題が起きてしまいます。

    return falseでバブリングを回避することが可能です。

    slickの使い方(カルーセルスライダー)

    slickはjQueryを使用したスライダーを作成することができるプラグインです。

    カスタマイズ性もあり、色んな場面で導入できます。

    https://kenwheeler.github.io/slick

    slickの使い方

    導入方法

    1. サイトからファイルにダウンロード
    2. CDNを利用

    1.ファイルをダウンロードする場合

    公式サイトから get it now のメニューの Download Now からダウンロード

    下記のファイルが必要となります

    • slick.css
    • slick-theme.css
    • slick.min.js
    <!-- css -->
    <link rel="stylesheet" href="slick/slick.css">
    <link rel="stylesheet" href="slick/slick-theme.css">
    <link rel="stylesheet" href="style.css"> //自分で記述するcssファイル
    <!-- js -->
    <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> //jQueryの読み込み
    <script src="slick/slick.min.js"></script>
    <script src="main.js"></script> //自分で記述するjsファイル

    2.CDNを利用する場合

    公式サイトから get it now のメニューから下記のようにコピペすればOK(※slick-theme.cssのリンクがない?

    ※2023年10月時点
    <!-- css -->
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick-theme.css">
    <link rel="stylesheet" href="style.css"> //自分で記述するcssファイル
    
    <!-- js bodyタグ終了直前-->
    <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> //jQueryの読み込み
    <script type="text/javascript" src="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>
    <script src="main.js"></script> //自分で記述するjsファイル

    ↑jsファイルをheadタグ内で読み込むと正しく動かない場合がある?

    slickのトラブル

    実装してみると、なぜか横スクロールが発生してしまいました。
    →overflow: hidden;をあてて解消しました。

    snow-monkeyだとうまく動かない?

    jsファイルはheadタグ内もしくは、bodyタグ終了直前?

    slickをWordPressで使用

    https://bizlabo.site/?p=1243
    https://siennahare23.sakura.ne.jp/wp-lesson/slick

    swiper

    スライダーの実装では、jQueryライブラリのSwiperがあります。

    https://kiomiru.co.jp/blog/coding/swiper-js

    jquery.inview

    inview.jsは要素がビューポートに入ったらクラスを付与することにより、いろんなイベントを発生させることができます。

    手順 1) jsファイルをダウンロード

    下記サイトよりダウンロードします。

    「jquery.inview.min.js」が必要になります。

    https://github.com/protonet/jquery.inview

    手順 2) ファイルを読み込む

    読み込んだファイルをディレクトリに配置し、htmlから読み込みの記述をします。

    <script src="js/jquery.inview.min.js"></script>

    ※jQueryも読み込みます。

    手順 3) htmlファイルにクラスを設定

    <div class="your-fade"></div>

    手順 4) CSSにフェード前後のスタイルを記述

    // フェードイン前
    .your-fade {
        opacity: 0;
        visibility: hidden;
        transform: translateY(40px);
        transition: 1s;
    }
    
    // フェードイン後
    .inview {
        opacity: 1;
        visibility: visible;
        transform: translateY(0px);
    }

    手順 4) jsファイルにコードを記述

    $(function () {
        $(".your-fade").on("inview", function () {
            $(this).addClass("inview");
        });
    });

    toggleClass

    toggleClassメソッドはjQueryを使って、引数に指定したクラスを追加したり、削除することができます。

    toggleClassの使い方

    $("要素").toggleClass("クラス名");
    
    要素‥クラスを追加、削除する対象
    クラス名‥追加、削除するクラス名

    scrollTop()メソッド

    scrollTop()メソッドはスクロール位置を取得することができます。

    スクロール量を取得
    
    対象要素.scrollTop();
    
    ※一般的なスクロール位置(ブラウザ全体)を取得する場合、対象要素をwindow

    スクロール位置を設定し移動

    引数の数値の位置まで移動します

    対象要素.scrollTop()
    
    ※値を設定することで、その位置まで移動

    fadeIn() fadeOut()

    fadeIn()は非表示になっている要素に対してフェードインのアニメーションを付与することができます。

    要素.fadeIn( 時間 );

    lightbox

    lightboxは画像をクリックすると拡大し、ポップアップ表示させたい場合に使用するJavaScriptライブラリです。

    lightbox導入手順

    lightboxのサイトで必要ファイルをダウンロードします。

    https://lokeshdhakar.com/projects/lightbox2

    最新バージョンからzipファイルをダウンロード

    必要ファイルを該当ディレクトリにおく

    必要なファイルは解凍したフォルダのdistフォルダ内にあります(表示速度が気になる場合に有効な圧縮版の軽量化されているminを使います)

    • lightbox.min.css
    • lightbox.min.js
    • images(フォルダ)

    例として下記のように配置した場合

    • index.html
    • css
      • lightbox.min.css
    • js
      • lightbox.min.js
    • images
      • close.png
      • loading.gif
      • next.png
      • prev.png
    • 拡大表示させた画像

    ファイルの読み込み

    htmlファイルに読み込みするため記述します

    headタグ内<link rel="stylesheet" href="css/lightbox.min.css" />

    body閉じタグ前に

    <!-- jQueryの読み込み -->
    <script
    src="https://code.jquery.com/jquery-3.7.1.min.js"
    integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
    crossorigin="anonymous"
    ></script>
    
    <!-- lightbox.min.jsの読み込み -->
    <script src="js/lightbox.min.js"></script>
    https://blanche-toile.com/web/javascript-lightbox

    ScrollHint

    画面幅を超えた横幅を横スクロールで表示する際、ブラウザによってスクロールバーの表示は常にしているとは限らないので、
    ユーザビリティの観点からこちらのライブラリでスクロールできることを明示することをお勧めします。

    実装例:

    https://siennahare23.sakura.ne.jp/oocss/#scrollh

    実装方法

    1)必要ファイルの読み込み

    CDNの場合(headタグ内):

    <link rel="stylesheet" href="https://unpkg.com/scroll-hint@latest/css/scroll-hint.css">
    <script src="https://unpkg.com/scroll-hint@latest/js/scroll-hint.min.js"></script>

    2)jsファイルの編集

    new ScrollHint('.js-scrollable');
    $(function(){
      new ScrollHint('.js-scrollable');
    });

    js-scrollableは任意のクラス名です

    2)htmlファイルの編集

    <div class="js-scrollable" style="overflow-x: scroll;">
     <table>
    
     …画面幅を超えるコンテンツ
    この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。この文章はダミーです。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。
    この文章はダミーです。この文章はダミーです。この文章はダミーです。この文章はダミーです。この文章はダミーです。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。
    この文章はダミーです。この文章はダミーです。この文章はダミーです。この文章はダミーです。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。この文章はダミーです。
    この文章はダミーです。この文章はダミーです。この文章はダミーです。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。この文章はダミーです。この文章はダミーです。
    https://jito-site.com/scrollhint-usage-option

    Web制作で使うJS

    JavaScriptはプログラミング言語で学習しようとすると、とても範囲が広いですがWeb制作で使うのは比較的基礎的な内容です。(Web開発とは違います)

    オススメの基本的な学習法

    • プロゲート
    • ドットインストール
    • Codejump
    https://code-jump.com/#coding-js

    サンプルページ

    https://siennahare23.sakura.ne.jp/jquery-design-lesson
    【PHP技術者認定試験問題】リクエスト情報、メールフォーム

    スーパーグローバル変数

    • どのスコープでも有効で無常記念でアクセス可能
    • global命令不要

    $_POST

    <form method="POST">タグでフォームから送信されたデータをポストデータといいます。

    $_GET

    $_GET … クエリ情報

    クエリ情報とはURLの末尾「~?」以降の「キー名=値」でセットされる情報です。

    $_SERVER

    リクエスト情報やサーバー変数を示します。

    ヘッダー情報

    PHPでメールフォームを作成

    コード内容

    • phpinfo.php
    • contactform.php

    phpinfo.php

    phpinfo()はPHPの情報を確認でき、PHPが動いている環境か確認できます。

    <?php
    phpinfo();
    ?>

    contactform.php

    <?php
      session_start();
    
      $mode = 'input';
      $errmessage = array();
    
      if( isset($_POST['back']) 
      // backという配列のキーがそもそも存在しているか
      // Noticeという注意文が出てしまう
    
      && $_POST['back'] ){
      // 空ではないか
    
      // if( $_POST['back']) {
        
      } else if( isset($_POST['confirm']) && $_POST['confirm'] ) {
      // 確認画面
    
        // 名前のバリデーション(入力チェック)
        if( !$_POST['fullname'] ) {
    	    $errmessage[] = "名前を入力してください";
        } else if( mb_strlen($_POST['fullname']) > 100 ){
    	    $errmessage[] = "名前は100文字以内にしてください";
        }
    	  $_SESSION['fullname'] = htmlspecialchars($_POST['fullname'], ENT_QUOTES);
        // サニタイズ(無害化)
    
        // メールのバリデーション
        if( !$_POST['email'] ) {
          $errmessage[] = "Eメールを入力してください";
        } else if( mb_strlen($_POST['email']) > 200 ){
          $errmessage[] = "Eメールは200文字以内にしてください";
        } else if( !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ){
          $errmessage[] = "メールアドレスが不正です";
        }
        $_SESSION['email'] = htmlspecialchars($_POST['email'], ENT_QUOTES);
    
        // お問い合わせ内容のバリデーション
        if( !$_POST['message'] ){
    		  $errmessage[] = "お問い合わせ内容を入力してください";
    	  } else if( mb_strlen($_POST['message']) > 500 ){
    		  $errmessage[] = "お問い合わせ内容は500文字以内にしてください";
    	  }
    	  $_SESSION['message'] = htmlspecialchars($_POST['message'], ENT_QUOTES);
    
        if( $errmessage ){
    	    $mode = 'input';
        } else {
    	    $mode = 'confirm';
        }
    
      } else if( isset($_POST['send']) && $_POST ) {
        $message = "お問い合わせを受け付けました。\r\n"
                  . "名前: " . $_SESSION['fullname'] . "\r\n"
                  . "email: " . $_SESSION['email'] . "\r\n"
                  . "お問い合わせ内容:\r\n"
                  . preg_replace("/\r\n|\r|\n/", "\r\n", $_SESSION['message']);
    	  mail($_SESSION['email'],'お問い合わせありがとうございます',$message);
        mail('xx@gmail.com','お問い合わせありがとうございます',$message);
        $_SESSION = array();
    
        $mode = 'send';
    
      } else {
        $_SESSION['fullname'] = "";
        $_SESSION['email']    = "";
        $_SESSION['message']  = "";
      }
    ?>
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>お問い合わせフォーム</title>
    </head>
    <body>
    
      <?php if( $mode == 'input' ) { ?>
        <!-- 入力画面 -->
        <h2>入力画面</h2><br>
        <?php
        if( $errmessage ){
          echo '<div style="color: red;">';
          echo implode('<br>', $errmessage );
          echo '</div>';
        }
        ?>
        <form action="./contactform.php" method="post">
          name<input type="text" name="fullname" value="<?php echo $_SESSION['fullname'] ?>"><br>
          email<input type="email" name="email" value="<?php echo $_SESSION['email'] ?>"><br>
          お問い合わせ内容<br>
          <textarea name="message" id="" cols="30" rows="10">
            <?php echo $_SESSION['message']; ?>
          </textarea><br>
          <input type="submit" name="confirm" value="確認">
        </form>
    
      <?php } else if( $mode == 'confirm' ){ ?>
        <!-- 確認画面 -->
        <h2>確認画面</h2><br>
        <form action="./contactform.php" method="post">
          name  <?php echo $_SESSION['fullname']; ?><br>
          email <?php echo $_SESSION['email']; ?><br>
          お問い合わせ内容 <br>
          <?php echo nl2br($_SESSION['message']); ?><br>
          <input type="submit" name="back" value="戻る" />
          <input type="submit" name="send" value="送信" />
        </form>
        
      <?php } else { ?>
        <!-- 完了画面 -->
        <h2>送信完了画面</h2><br>
        送信しました。お問い合わせありがとうございました。<br>
      <?php } ?>
     
      <?php
      print_r($_POST );
      ?>
      
    </body>
    </html>
    https://siennahare23.sakura.ne.jp/hinkon/contactform.php

    メールフォームのセキュリティについて

    クロスサイトスクリプティング対策

    htmlspecialcharsという関数を使いエスケープ処理を行います。

    スクラッチ以外の利用

    実際はWordPressのプラグインやメールフォームのライブラリ(PHPMailer、Laravel)を使用するのが鉄板で無難です。

    完全なセキュリティは難しい

    セキュリティを十分に考慮されたシステムには、それなりにコストがかかります。

    制作しているサイトが、相応の重要なデータを扱っているかを考える必要があります。

    【PHP技術者認定試験問題】リクエスト情報

    リクエスト情報を取得、操作するためのスーパーグローバル変数 8
    $_POSTPOST形式で渡された情報
    $_GETクエリ情報経由で渡された情報
    $_FILESアップロードされたファイルに関する情報
    $_SERVERリクエストヘッダー、またはサーバー固有の変数情報
    $_ENVサーバー側で定義された環境変数
    $_COOKIEクッキー経由で渡された情報
    $_SESSIONセッション経由で渡された情報
    $_REQUEST$_GET、$_POST、$_COOKIEの値をまとめて管理
    ユーザーからの入力値をブラウザーに表示させる場合の注意点

    htmlspecialchars()関数でエスケープすることで、クロスサイトスクリプティング攻撃を防ぎます

    主なサーバー変数 7
    $_SERVER[‘PHP_SELF’]Webサーバに要求するURL
    $_SERVER[‘SERVER_NAME’]PHPは実行されているWebサーバの名前
    $_SERVER[‘SERVER_ADDR’]IPアドレス
    $_SERVER[‘REQUEST_METHOD’]リクエストのメソッド名
    $_SERVER[‘REMOTE_ADDR’]ユーザの IP アドレス
    $_SERVER[‘REMOTE_HOST’]現在のページにアクセスしているホストの名前
    $_SERVER[‘QUERY_STRING’]検索引数
    ・名前「name」、値「value」有効期限30日後のクッキーを発行してください
    ・クッキーを即座に破棄してください
    setcookie('name', 'value', time() + 60 * 60 * 24 * 30);
    setcookie('name', 'value', time() - 3600);
    クッキーを定義する関数は
    setcookie(name, value, expire, path, domain, secure, httponly)
    
    1.name … クッキーの名前
    2.value … クッキーの値
    3.expire … 有効期限
    4.path … URLのパス
    5.domain … 有効なドメイン
    6.secure … secure属性(HTTPS通信時のみ許可)
    7.httponly … httponly属性(JavaScriptによるクッキーの操作を防ぐ)

    【PHP技術者認定試験問題】ユーザ定義関数、標準クラスライブラリ

    ユーザ定義関数

    ・ユーザ定義関数で引数、戻り値を明示的に指定すること
    ・記述方法
    ・型名 6

    宣言型

    function ファンクション名 (引数の型 引数, 引数の型 引数): 戻り値の型 {
      …
    }
    bool真偽値
    float浮動小数点数
    int整数
    string文字列
    callableコールバック関数
    void何も返さない(戻り値のみ指定可)
    指定化
    下記のprocessNumberは$num、…を引数$funcで処理し、結果を配列として返す関数です。

    function processNumber( 1 $func, float …$args): array {
    foreach ( 2 as $arg) {
    $result[] = 3;
    }
    return $result;
    }
    4 $x, $y 5 = processNumber(
    fn($num) 6
    5, 15);
    function processNumber( callable $func, float ...$args): array {
      foreach ( $args as $arg) {
        $result[] = $func($arg);
      }
      return $result;
    }
    [ $x, $y ] = processNumber(
      fn($num) => $num**2
      5, 15);

    標準クラスライブラリ

    日付文字列「2023年8月3日」を、DateTimeクラスを使ってかいせきし、「YYYY/MM/DD(曜日)」の形式で出力してください
    $dt = 1::2(‘Y年m月d日’, ‘2023年8月3日’);
    print $dt->3(‘Y/m/d (D)’);
    $dt = DateTime::createFromFormat('Y年m月d日', '2023年8月3日');
    print $dt->format('Y/m/d (D)');
    format文字
    j、d、D、n、m、M、y、Y、g、G、i、s
    j日付(1~31)
    d日付(01~31)
    D曜日(Mon~Sun)
    n月(1~12)
    m月(01~12)
    M月(Jan~Dec)
    y年(2桁)
    Y年(4桁)
    g時(1~12)
    G時(0~23)
    i分(0~59)
    s秒(0~59)
    インスタンスメソッドの呼び出し

    ->アロー演算子

    日付/時刻を指定のフォーマットで整形するメソッド

    format

    $dt = 1 2(‘2022/8/4 10:26:30’);
    print $dt->3(‘Y年m月d日 H時i分’); // 結果:2022年08月04日 10時26分
    $dt->4(1 5(‘P1YT10H’));
    print $dt->3(‘Y年m月d日 H時i分’); // 結果:2023年08月04日 20時26分
    $dt = new DateTime('2022/8/4 10:26:30');
    print $dt->format('Y年m月d日 H時i分');  // 結果:2022年08月04日 10時26分
    $dt->add(new DateInterval('P1YT10H')); 
    print $dt->format('Y年m月d日 H時i分');  // 結果:2023年08月04日 20時26分
    $dt1 = new 1(‘2020/8/20 10:38:32’);
    $dt2 = new 1(‘2023/12/10’);
    $interval = $dt1->2($dt2, true);
    $dt1 = new DateTime('2020/8/20 10:38:32');
    $dt2 = new DateTime('2023/12/10');
    $interval = $dt->diff($dt2, true);
    ・指定されたフォルダーにディレクトリ配下のファイル情報にアクセスするためのクラス
    ・上記クラスの主なメソッド
     ・ファイルがフォルダーであるか
     ・ファイルが通常のファイルであるか
    new DirectoryIterator(string $path)
    • is_dir($path)
    • is_file($path)
    Shadcn/UI 入門:React で洗練された UI コンポーネントを作る

    こんにちは! 今回は、React のプロジェクトで洗練された UI コンポーネントを簡単に作成できる「shadcn/ui」について紹介します。Web 開発をしていると「もっとスタイリッシュなコンポーネントを作りたいけど、手間がかかるなあ…」と感じたことはありませんか?Shadcn/ui はそんな悩みを解決してくれる強力なツールです!


    Shadcn/UI って何?

    shadcn/ui は、React や Next.js プロジェクトに簡単に統合できる UI コンポーネントライブラリです。このツールは、デザインの美しさと使いやすさに重点を置いており、あらかじめスタイリングされたコンポーネントが豊富に揃っています。デフォルトで美しいスタイルを持っているので、開発者はデザインに悩まずに素早くページを作成できます。

    特徴

    • 洗練されたデザイン:すぐに使える美しいデザインが標準で搭載。
    • カスタマイズ性:基本スタイルを維持しつつ、自分のプロジェクトに合わせて簡単に調整可能。
    • 開発スピード向上:手間をかけずに UI を組み込めるので、実装にかかる時間を大幅に短縮。

    Shadcn/UI を使ってみる

    それでは、実際に Shadcn/UI をインストールし、React プロジェクトに組み込んでみましょう。以下では、インストールから基本的な使用方法までを説明します。

    1. インストール

    まず、以下のコマンドを使って Shadcn/UI をインストールします。

    npm install shadcn-ui

    インストールが完了したら、React または Next.js プロジェクトに shadcn/ui をインポートして使えるようになります。

    2. 基本的な使い方

    例えば、ボタンコンポーネントを作りたい場合、以下のように Button コンポーネントを使います:

    import { Button } from 'shadcn-ui';
    
    function App() {
      return (
        <div>
          <Button onClick={() => alert("ボタンがクリックされました!")}>クリック!</Button>
        </div>
      );
    }
    
    export default App;

    このコードを実行すると、下のような美しいボタンが表示されます。

    3. コンポーネントのカスタマイズ

    shadcn/ui のコンポーネントは、カスタマイズも簡単です。例えば、ボタンの色を変えたり、サイズを調整する場合、Button コンポーネントのプロパティを設定するだけで見た目を変更できます。

    <Button color="primary" size="large">カスタムボタン</Button>

    おすすめのコンポーネント

    Shadcn/UI には、ボタン以外にも以下のような便利なコンポーネントが用意されています:

    1. カード (Card)
      コンテンツを整理して表示するのに最適。
    2. モーダル (Modal)
      ポップアップウィンドウを簡単に追加可能。
    3. トグル (Toggle)
      スイッチのようなオンオフの切り替え UI。

    カスタムテーマの設定

    Shadcn/UI では、デフォルトのテーマをプロジェクトに合わせて変更することもできます。カスタムテーマの設定は以下のように行います:

    import { ThemeProvider } from 'shadcn-ui';
    
    function App() {
      return (
        <ThemeProvider theme="dark">
          <Button>ダークテーマボタン</Button>
        </ThemeProvider>
      );
    }

    まとめ

    shadcn/ui は、React や Next.js のプロジェクトでおしゃれで使いやすい UI を簡単に構築できる強力なツールです。デザインに時間をかけずにプロジェクトの UI を整えたい方に特におすすめです。興味のある方はぜひインストールして試してみてください!

    Docker 環境で WordPress を使用している場合「アップロードされたファイルが php.ini の upload_max_filesize ディレクティブを越えています。」について

    upload_max_filesize」と関連する設定を変更手順

    1)カスタム php.ini ファイルを作成

    custom-php.ini という名前のファイルを作成し、以下の内容を追加

    ※docker-compose.ymlと同じディレクトリに作成

    upload_max_filesize = 64M
    post_max_size = 64M
    memory_limit = 128M

    ※値は必要に応じて調整してください。

    2)docker-compose.yml ファイルを編集

    services:
      wordpress:
        image: wordpress:latest
        volumes:
          - ./custom-php.ini:/usr/local/etc/php/conf.d/custom-php.ini
        # 他の設定...

    3)コンテナを再起動

    docker-compose down
    docker-compose up -d

    再起動後、再度WordPressインストールし最大アップロードサイズを確認すると変更されているのが確認できました

    PHPサンプルコード

    標準入力

    <?php
        // 標準入力がHelloの場合こんにちはを出力
    
        $greeting = trim(fgets(STDIN));
        if ($greeting == "Hello") {
            echo "こんにちは\n";
        }
    ?>
    <?php
        // 1. 標準入力から文字列を 1 個受け取る
        // 2. その文字列が「Hello」に等しい場合、次のメッセージを表示する
        // こんにちは
        // 3. 「Hello」に等しくない場合、次のメッセージを表示する
        // AAAはHelloではない    ※AAAに、その文字列を当てはめる
    
        $name = trim(fgets(STDIN));
        if ($name == "Hello") {
            echo "こんにちは\n";
        } else {
            echo $name . "はHelloではない\n";
        }
    ?>

    文字変換

    <?php
    // ファイル名に含まれる長さ 2 以上のハイフンをすべて長さ 1 にしたファイル名を文字列で出力してください。
    // ファイル名の文字列は100字以内
    
    $stdin = trim(fgets(STDIN));
    
    for($i = 100; $i >= 1; $i--){ 
    
        $repeat_count = $i;
        $text = str_repeat("-", $i);
    
        $stdin = str_replace($text, "-", $stdin);
    }
    
    echo $stdin;
    ?>

    複数行入力

    <?php
    
    // ・1 行目には、あなたの食べたい料理名を表す文字列 S が与えられます。
    // ・2 行目には、与えられるメニューの単語数を表す整数 N が与えられます。
    // ・3 行目には、メニュー名を表す単語の文字列 T_i (1 ≦ i ≦ N) が半角スペース区切りで与えられます。
    // ・入力は全部で 3 行となり、最終行末尾に改行が一つ入ります。
    // 与えられたメニューがあなたの食べたい料理であれば "Yes" を、そうでなければ "No" を出力してください。
    
    // 標準入力を一行ずつ配列に代入
    while ($stdin = trim(fgets(STDIN))) {
        $stdin_array[] = $stdin;
    }
    
    $my_menu = $stdin_array[0];
    
    $menu_count = --$stdin_array[1];
    
    $menu_array = explode(' ',$stdin_array[2]);
    
    for($i = 0; $i <= $menu_count; $i++){ 
    
        $menu_word = $menu_array[$i];
    
    
        
        // "Yes" を、そうでなければ "No"
        if ($my_menu == $menu_word) {
            echo "Yes";
            break;
        } elseif ($my_menu != $menu_word && $i == $menu_count) {
            echo "No";
            break;
        }
    }
    
    ?>

    多重ループ
    多次元配列

    <?php
    
    // ・1 行目にクラスの人数を表す整数 N が与えられます。
    // ・続く N 行のうちの i 行目 (1 ≦ i ≦ N) には、i 番目の生徒が投票したクラスメイトの名前 a_i が与えられます。
    // ・入力は合計で N + 1 行となり、入力値最終行の末尾に改行が 1 つ入ります。
    // ・最も得票数の多い人は 1 人のみです。
    
    while ($stdin = trim(fgets(STDIN))) {
        $stdin_array[] = $stdin;
    }
    
    $num_peaple = $stdin_array[0];
    
    for($i = 1; $i <= $num_peaple; $i++) { 
    
        $count = 0;
    
        for($j = $i; $j <= $num_peaple; $j++) {
    
            if ($stdin_array[$i] == $stdin_array[$j]) {
    
                $count++;
    
            }
    
        }
        
        // 多次元配列値追加
        $count_array[] = [$stdin_array[$i], $count];
    }
    
    
    // 抽出
    $cols = array_column($count_array, 1); 
    // echo print_r($cols);
    
    array_multisort($cols, SORT_DESC, $count_array);
    // echo print_r($count_array);
    
    echo $count_array[0][0];
    
    ?>
    Webセキュリティを考慮してフォーム作成
    • 正常系をまず作成
    • 異常系を考える、テストする、キリがない
    • マストな異常系をルール化する(経験がものをいう)
    • 失敗する前提で記述
    • 失敗のログがでるように
    • 時間をおいてお試してください
    • SQLインジェクション、CSRF
      →参考:体系的に学ぶ 安全なWebアプリケーションの作り方 第2版[固定版] 脆弱性が生まれる原理と対策の実践

    POSTリクエストはContent-Typeはapplication/json

    POSTリクエストを使うとき、サーバーにデータを送信する形式を示すために「Content-Type」というヘッダーを設定する

    application/json

    • JSON形式でデータを送信するときに使います。
    • 例えば、フォームデータをJavaScriptでオブジェクトにして送信したい場合に利用します。

    正常系を完成させる

    フロントエンドからのフォームデータ送信

    script.jssendMail 関数で、axiosを使ってフォームデータをsendMailer.phpに送信しています​(script)。まず、データが正しくサーバーに送信されているかを確認します。

    PHP側でのデータ受信とレスポンス

    sendMailer.php で、送信されたデータを受け取り、PHPMailerを用いてメールを送信する処理を追加します。現状のコードでは、PHPMailerの処理が未実装ですので、これを追加します。

    フロントエンドでの成功メッセージの表示

    メール送信が正常に完了した場合、フロントエンドで成功メッセージを表示させます。すでに sendMail 関数内でレスポンスに基づく処理が行われているため、サーバーから成功レスポンスが返ってきた際に次のページにリダイレクトするか、成功メッセージを表示するように設定します。

    memo

    デフォルトでは Content-Type が application/json になりますが、PHP で $_POST を使用してデータを取得するには application/x-www-form-urlencoded 形式で送信する必要がある

    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>フォーム送信</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <div class="form_wrap">
            <form class="form" onSubmit="handleSubmit(event)" name="cta_form">
                <p class="form_title">form</p>
                <div class="form_area">
                    <!-- メールアドレス入力欄 -->
                    <input class="form_input" type="email" name="email" placeholder="メールアドレス" required>
                    <div class="err" id="emailError"></div>
                    
                    <!-- 電話番号入力欄 -->
                    <input class="form_input" type="tel" maxlength="11" name="tel" placeholder="例) 09012345678" required>
                    <div class="err" id="telError"></div>
    
                    <!-- 送信ボタン -->
                    <button class="submit" type="submit">送信</button>
                </div>
            </form>
        </div>
        <div id="formMessage" class="form_message"></div>
    
        <!-- JavaScriptの読み込みをbodyの最後に移動 -->
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
        <script src="script.js"></script>
    </body>
    </html>
    
    $(document).ready(function () {
        async function sendMail(formData) {
            try {
                const url = "https://siennahare23.sakura.ne.jp/1104_tokuform/sendMailer.php";
                console.log("送信データ:", formData);
    
                const res = await axios.post(url, JSON.stringify(formData), {
                    headers: {
                        "Content-Type": "application/json",
                    },
                });
    
                const json = res.data;
                console.log("サーバーからのレスポンス:", json);
    
                return { success: json.status === "success", data: json };
            } catch (error) {
                console.error("PHPへの送信エラー:", error);
                return { success: false, error: error };
            }
        }
    
        window.handleSubmit = async function (event) {
            event.preventDefault();
            const form = event.currentTarget;
    
            // 入力要素の取得
            const emailInput = form.querySelector('input[name="email"]');
            const telInput = form.querySelector('input[name="tel"]');
            const emailValue = emailInput.value;
            const telValue = telInput.value;
    
            // 電話番号とメールアドレスのバリデーション
            if (telValue.length !== 11 || !/^\d{11}$/.test(telValue)) {
                document.getElementById("telError").innerText = "11桁の電話番号を入力してください";
                return;
            } else {
                document.getElementById("telError").innerText = "";
            }
    
            if (!/^[\w\.-]+@[\w\.-]+\.\w+$/.test(emailValue)) {
                document.getElementById("emailError").innerText = "有効なメールアドレスを入力してください";
                return;
            } else {
                document.getElementById("emailError").innerText = "";
            }
    
            // フォームデータの収集
            const data = new FormData(form);
            const formData = Object.fromEntries(data.entries());
    
            const result = await sendMail(formData);
    
            // メッセージ表示要素を取得
            const messageDiv = document.getElementById("formMessage");
    
            // 成功・失敗のメッセージを表示
            if (result.success) {
                messageDiv.innerText = result.data.message || "メールが正常に送信されました";
                messageDiv.style.color = "green";
            } else {
                messageDiv.innerText = result.data.message || "送信エラーが発生しました。再度お試しください。";
                messageDiv.style.color = "red";
            }
        };
    });
    <?php
    // 設定ファイルの読み込み
    require_once '/home/siennahare23/config/config.php';
    
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;
    
    require 'vendor/autoload.php';
    
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        // JSON データの取得と解析
        $input = file_get_contents('php://input');
        $data = json_decode($input, true);
    
        // 入力データの取得
        $email = filter_var($data['email'], FILTER_SANITIZE_EMAIL);
        $tel = filter_var($data['tel'], FILTER_SANITIZE_STRING);
    
        // デバッグ情報の出力
        // echo '取得したメールアドレス: ' . htmlspecialchars($email) . '<br>';
        // echo '取得した電話番号: ' . htmlspecialchars($tel) . '<br>';
    
        // メールアドレスの検証
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            echo '無効なメールアドレスです: ' . htmlspecialchars($email);
            exit;
        }
    
        // 電話番号の検証
        if (!preg_match('/^\d{11}$/', $tel)) {
            echo '無効な電話番号です: ' . htmlspecialchars($tel);
            exit;
        }
    
        // デバッグ情報の出力
        // echo '送信先メールアドレス: ' . htmlspecialchars($email) . '<br>';
        // echo '送信先電話番号: ' . htmlspecialchars($tel) . '<br>';
    
        $mail = new PHPMailer(true);
    
        try {
            // SMTP設定
            $mail->isSMTP();
            $mail->Host       = SMTP_HOST;
            $mail->SMTPAuth   = true;
            $mail->Username   = SMTP_USER;
            $mail->Password   = SMTP_PASS;
            $mail->SMTPSecure = SMTP_SECURE;
            $mail->Port       = SMTP_PORT;
    
            // エンコーディングの設定
            $mail->CharSet = 'UTF-8';
            $mail->Encoding = 'base64';
    
            // 送信者と受信者の設定
            $mail->setFrom(SMTP_USER, 'Mailer'); // 送信者
            $mail->addAddress($email); // 受信者
    
            // メール内容の設定
            $mail->isHTML(true);
            $mail->Subject = 'フォーム送信内容';
            $mail->Body    = 'メールアドレス: ' . htmlspecialchars($email) . '<br>電話番号: ' . htmlspecialchars($tel);
            $mail->AltBody = 'メールアドレス: ' . htmlspecialchars($email) . "\n電話番号: " . htmlspecialchars($tel);
    
            // メール送信
            $mail->send();
            echo json_encode(['status' => 'success', 'message' => 'メッセージが送信されました']);
    
        } catch (Exception $e) {
            echo json_encode(['status' => 'error', 'message' => "メッセージを送信できませんでした。エラー: {$mail->ErrorInfo}"]);
        }
    } else {
        echo json_encode(['status' => 'error', 'message' => 'POSTメソッドで送信してください。']);
    }
    ?>
    All-in-One WP Migration

    インポート容量を引き上げる方法

    All-in-One WP Migrationではインポートの容量制限があるため、ファイルサイズが1GB以上のものは、データ移行ができません。

    インポート容量上限をあげるには以下の方法があります。

    • 有料版を使う
    • 無料版の容量を上げる

    有料版に関しては、All-in-One WP Migration unlimited extensionの買い切り版は販売が終了しており、1年ごとのサブスクリプションとなっています。

    無料版all-in-one wp migrationの容量を上げる方法 パート1

    1.「all-in-one wp migration ver.6.68」をダウンロード

    ↑2024/03/04問題なく使用可能

    2. インストール

    3. ソースコードを編集

    「all-in-one wp migration」プラグインの「constants.php」ファイルにて編集します。

    * 20 を末尾に追記します。

    // =================
    // = Max File Size =
    // =================
    define( 'AI1WM_MAX_FILE_SIZE', 536870912 * 20 );
    https://www.caliberelectronics.com/all-in-one-wp-migration/

    無料版all-in-one wp migrationの容量を上げる方法 パート2(2024/01/10)

    ローカル環境の場合

    php.iniを編集します。

    テーマフォルダ/con/php/php.ini.hbs

    レンタルサーバの場合

    よくあるエラー

    インポートが終わらない

    • データベースが読み込めない。
    • php のバージョンが一致していない。

    SiteGuard WP Pluginとの相性

    データ移行後WordPressにログインできないトラブルが起きることがあります。(ログインページが404

    プラグイン「SiteGuard WP Plugin」が原因の場合があります。無効化後データ移行をする必要があります。

    https://design-pull.com/wordpress/6812/
    【PHP技術者認定試験問題】
    PDOのエラー処理3通りとは
    • PDO::ERRMODE_SILENT PHP(デフォルト)
      例外を発行せず、プログラムは続行
    • PDO::ERRMODE_WARNING
      例外を発行せず、メッセージも出力、プログラムは続行
    • PDO::ERRMODE_EXCEPTION(PHP 8.0.0 以降では、デフォルト)
      PDOException をスロー、例外を処理しない場合プログラムを停止
    ・Webサーバが保持しているセッションのデータを破棄する関数は
    ・変数保存用領域も破棄
    • session_unset
    • session_destroy
    PHPでどのエラーを報告するかを設定する構成ディレクティブは

    error_reporting構成ディレクティブ

    PHPで取り扱うことができる代表的なエラー5つとは
    Parse Errorプログラムに構成上の問題があるE_PARSE
    Fatal Error
    (致命的なエラー)
    プログラムの内容に関わる重大の問題がある
    発生した場合は処理を停止
    E_ERROR
    Warningプログラムに疑わしい箇所があるE_WARNING
    Notice
    (注意)
    マナー違反のまま動作しているE_NOTICE
    Strict Notice
    (厳格注意)
    コーディングスタイルについての注意E_STRICT
    PHP付属のデバッガとは

    phpdbgデバッガ

    ユーザ定義の例外ハンドラを設定する関数とは
    (未補足の例外(try/catchブロックで例外をキャッチできない)場合に備えて)

    set_exception_handler

    PHPコードの単体テストを記述するツールは

    PHPUnit

    UNIX/Linux環境で全ユーザに対して実行権を追加するchmodコマンド
    chmod a+x ファイル名

    chmod ①②③ ファイル名

    1. u:所有ユーザ、w:所有グループ、a:全ユーザ
    2. +:権限を与える、-:権限を取り除く
    3. r:読み取り権、w:書き込み権、x:実行権
    Packagistとは

    代表的なComposerパッケージリポジトリ(インストール可能なパッケージの一覧)

    phpコマンド 7
    オプション名
    -S組み込みサーバを開始
    -hコマンドのヘルプを表示
    -mPHPに組み込まれたモジュールを表示
    -aPHPを対話的に実行(PHP REPL)
    ※REPLとは 入力・評価・出力をできる対話型実行環境
    -t組み込みWebサーバのドキュメントルートを設定
    -d設定ファイル(php.ini)で設定ディレクティブにカスタム値を設定
    -iphpinfo()関数を実行し、PHPの設定情報を出力
    php -S Webサーバ名:ポート番号
    配列はスカラー変数に代入可能か

    可能、スカラー変数を配列に代入も可能

    このとき、古いデータ型から新しいデータ型に置き換わります

    MySQLのデータソース名の構文とは
    $dsn = "mysql:host={$host_name};port=8889;dbname={$db_name}";
    /データベースへの接続
    $db = new PDO('データソース名', 'ユーザ名', 'パスワード');

    関数内でグローバル変数にアクセスする方法で、使用するグローバル変数格納している配列は

    $GLOBALS

    グローバル変数は通常、関数外部のみで有効になりますが、配列$GLOBALSは関数内でもアクセスが可能です。

    $num1 = 30;
    foo();
    function foo() {
     print $GLOBALS['num'];
    }
    <?php

    1 {
    //throw new 例外クラス名(引数)でインスタンスを作成
    2(‘例外処理発生’); }
    3(Exception $e) {

    echo $e->4;
    }

    ?>
    1. try
    2. throw new Exception
    3. catch
    4. getMessage()
    1 ファイルの内容を読み込む ○○ (○○)

    2 文字列をファイルに書き込む ○○(○○,○○)
    1. file_get_contents (ファイル名)
    2. file_put_contents ( ファイル名 , 文字列 )
    1 ファイルへの接続をオープン
    ○○(○○, ○○)関数

    2 読み書き
    ○○()関数、○○()関数

    3 ファイルをクローズ
    ○○()関数
    1. ファイルへの接続をオープン
      fopen(ファイル名, ファイルのモード)関数
    2. 読み書き
      fgets()関数、fwrite()関数
    3. ファイルをクローズ
      fclose()関数
    フレームワークLarabel、Symfony、Zend Frameworkのテンプレートエンジンは

    ※動的な処理プログラムと表示内容を記述したHTMLを別で管理する仕組みです
     テンプレート(HTMLのひな型)を必要に応じて書き換えて画面に出力するライブラリ

    Larabel Blade
    Symfony Twig
    Zend Framework PHP

    php.iniの記述で
    1 Webブラウザにエラーメッセージを表示するには
    2 Webサーバにエラーログを送信するには
    1. display_errors構成ディレクティブを「On」
    2. log_errors構成ディレクティブを「On」
    PHPUnitでアサーションメソッドの一つです。1つ目と2つ目の引数が一致しない場合にエラーを報告

    assertEquals()

    fopen()のファイルのモードで
    1 元のファイルをクリアして上書きしたい場合
    2 追加で書き込みしたい場合
    1. w(wb?)
    2. a(ab?)
    curl_setopt 6
    オプション
    CURLOPT_RETURNTRANSFERTRUEを設定すると、curl_exec()関数の返り値を文字列で返す
    CURLOPT_HEADERTRUEを設定するとヘッダの内容も出力する
    CURLOPT_POSTTRUEを設定するとPOSTのリクエストを宣言する
    CURLOPT_POSTFIELDSHTTP POST で送信するデーターを設定する
    CURLOPT_COOKIEJAR・TRUEを指定するとクッキーを追跡する
    ・ファイル名を指定すると指定のファイルにクッキーの情報が保存される
    CURLOPT_COOKIEFILEクッキーのファイルを指定することでクッキーの情報を読み込む