Overview

Namespaces

  • SKJ
    • AppException
      • HTTP
      • Logic
      • Runtime

Classes

  • SKJ\Label

Interfaces

  • SKJ\AppExceptionInterface

Traits

  • SKJ\AppExceptionMethods

Exceptions

  • SKJ\AppException
  • SKJ\AppException\AbstractContainerException
  • SKJ\AppException\AbstractDateTimeException
  • SKJ\AppException\AbstractHttpException
  • SKJ\AppException\AbstractValidationException
  • SKJ\AppException\HTTP\BadGatewayException
  • SKJ\AppException\HTTP\BadRequestException
  • SKJ\AppException\HTTP\ConflictException
  • SKJ\AppException\HTTP\ExpectationFailedException
  • SKJ\AppException\HTTP\FailedDependencyException
  • SKJ\AppException\HTTP\ForbiddenException
  • SKJ\AppException\HTTP\GatewayTimeoutException
  • SKJ\AppException\HTTP\GoneException
  • SKJ\AppException\HTTP\HttpVersionNotSupportedException
  • SKJ\AppException\HTTP\InternalServerErrorException
  • SKJ\AppException\HTTP\LengthRequiredException
  • SKJ\AppException\HTTP\LockedException
  • SKJ\AppException\HTTP\MethodNotAllowedException
  • SKJ\AppException\HTTP\NotAcceptableException
  • SKJ\AppException\HTTP\NotFoundException
  • SKJ\AppException\HTTP\NotImplementedException
  • SKJ\AppException\HTTP\PaymentRequiredException
  • SKJ\AppException\HTTP\PreconditionFailedException
  • SKJ\AppException\HTTP\ProxyAuthenticationRequiredException
  • SKJ\AppException\HTTP\RequestedRangeNotSatisfiableException
  • SKJ\AppException\HTTP\RequestEntityTooLargeException
  • SKJ\AppException\HTTP\RequestTimeoutException
  • SKJ\AppException\HTTP\RequestUriTooLongException
  • SKJ\AppException\HTTP\ServiceUnavailableException
  • SKJ\AppException\HTTP\UnauthorizedException
  • SKJ\AppException\HTTP\UnprocessableEntityException
  • SKJ\AppException\HTTP\UnsupportedMediaTypeException
  • SKJ\AppException\HttpException
  • SKJ\AppException\Logic\BadFunctionCallException
  • SKJ\AppException\Logic\BadMethodCallException
  • SKJ\AppException\Logic\CircularReferenceException
  • SKJ\AppException\Logic\ContainerException
  • SKJ\AppException\Logic\DependencyInjectionException
  • SKJ\AppException\Logic\DomainException
  • SKJ\AppException\Logic\EnvironmentException
  • SKJ\AppException\Logic\InvalidArgumentException
  • SKJ\AppException\Logic\LengthException
  • SKJ\AppException\Logic\OutOfRangeException
  • SKJ\AppException\Logic\UnexpectedValueException
  • SKJ\AppException\LogicException
  • SKJ\AppException\Runtime\AuthenticationException
  • SKJ\AppException\Runtime\DeadLockException
  • SKJ\AppException\Runtime\DuplicationException
  • SKJ\AppException\Runtime\DurationException
  • SKJ\AppException\Runtime\EmptyResultException
  • SKJ\AppException\Runtime\ExpiryException
  • SKJ\AppException\Runtime\InvalidElementException
  • SKJ\AppException\Runtime\MissingElementException
  • SKJ\AppException\Runtime\NoConditionException
  • SKJ\AppException\Runtime\OutOfBoundsException
  • SKJ\AppException\Runtime\OverflowException
  • SKJ\AppException\Runtime\PermissionException
  • SKJ\AppException\Runtime\RangeException
  • SKJ\AppException\Runtime\TemporaryFailureException
  • SKJ\AppException\Runtime\TimeoutException
  • SKJ\AppException\Runtime\TransactionException
  • SKJ\AppException\Runtime\UnavailableServiceException
  • SKJ\AppException\Runtime\UnderflowException
  • SKJ\AppException\Runtime\UnexpectedValueException
  • SKJ\AppException\Runtime\UploadException
  • SKJ\AppException\Runtime\ValidationException
  • SKJ\AppException\Runtime\WrongArgumentException
  • SKJ\AppException\RuntimeException
  • Overview
  • Namespace
  • Class
  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 
<?php
// このファイルの名前空間の定義
namespace SKJ;

// 別名定義
use InvalidArgumentException;
use LogicException;

/**
 * ラベル作成
 *
 * ソースファイルの行番号ベースの定数ラベルを作成します
 *
 * ◆詳細◆
 *
 * 基本的なラベル作成は下記のような形となる(行頭の数字はソースラベル行)
 *
 * <code>
 * 1:$label = new Label(1); // 引数は行補正
 * 2:$label->L01(); // 基本的なラベル作成方法
 * 3:$label->L02(-1); // 引数は別の行補正値を渡せる
 * 4:Label::L03(); // 静的コンテキストでも可能
 * 5:echo $label->L_L01; // 2(実際のソース上のラベル作成行)
 * 6:echo $label->L_L02; // 2(実際のソース上のラベル作成行+コンストラクタの行補正)
 * 7:echo L_L03; // 3(静的に作成した場合は定数のみで参照可能)
 * </code>
 *
 * 実際の使用方法はphp-app-exceptionと組み合わせて下記のように使用される
 *
 * <code>
 * use SKJ\Label;
 *
 * function selectUser($name)
 * {
 *     if(!($result = readDbByUser($name))){
 *         throw new \SKJ\AppException('user not found!!');
 *     }
 *
 *     return $result;
 * }
 *
 * try {
 *
 *     Label::L001();$result = selectUser('佐藤');
 *     Label::L002(1); // ラベルが指し示したい行が次行なので行補正で1を渡す
 *         $result = selectUser('鈴木');
 *
 *     var_dump($result);
 *
 * } catch (\SKJ\AppException $e) {
 *
 *     // 受け取った例外がこのスコープの何行目で発生したものかで分岐
 *     switch ($e->getLineInCurrentContext()) {
 *         case L_L001:
 *             die('佐藤さんは在籍していません!!');
 *         case L_L002:
 *             die('鈴木さんは在籍していません!!');
 *     }
 * }
 * </code>
 *
 * 例外キャッチ時にキャッチと同一スコープ上のどの行から発生した例外か識別できる
 *
 * これはtry~catch間で同一の関数、メソッドを複数回呼び出す(例外が同一クラス、同一例外コードで返ってくる)ようなケースで利用できる
 *
 * ※なお、発生行はセミコロンのある行となる
 *
 * <code>
 * 例)
 * 01: Label::L001();$users = selectUsers(
 * 02:     'where deleted=0',
 * 03:     'order by index desc'
 * 04: );
 * </code>
 *
 * このようなケースでは例外の発生行は4となる
 *
 * @package SKJ\Label
 * @author y3high <y3public@49364.net>
 * @copyright 2019 Seikouhou.
 * @license https://opensource.org/licenses/MIT MIT
 * @since Class available since Release 0.8.0
 */
class Label
{
    /**
     * @api
     * @var int 行補正値
     */
    public static $correctedLine = 0;
    /**
     * @api
     * @var string ラベル接頭詞
     */
    public static $labelPrefix = 'L';
    /**
     * @internal
     * @var array 内部ラベル配列
     */
    private $label = [];

    /**
     * コンストラクタ
     *
     * クラスの初期化です
     *
     * @api
     * @param int $correctedLine ラベルが指し示す場所への行補正
     */
    public function __construct($correctedLine = null)
    {
        if (is_numeric($correctedLine)) {

            self::$correctedLine = (int)$correctedLine;
        }
    }

    /**
     * ラベル作成処理
     *
     * 指定された名前で定数ラベルを作成する
     *
     * @api
     * @param string $name ラベル名称
     * @param int $correctedLine ラベルが指し示す場所への行補正
     * @param array $trace debug_backtrace関数の戻り値
     * @param Label|null $_this インスタンス
     * @throws \InvalidArgumentException 引数異常
     */
    private static function makeLabel(
        $name,
        $correctedLine,
        array $trace,
        Label $_this = null
    ){
        if (is_string(self::$labelPrefix) and self::$labelPrefix !== '') {

            $labelName = self::$labelPrefix.'_'.$name;

        } else {

            throw new InvalidArgumentException('ラベルが間違っています', 1);
        }

        if (is_numeric($correctedLine)) {

            $correctedLine = (int)$correctedLine;

        } else {

            throw new InvalidArgumentException(
                '行補正値が間違っています', 2
            );
        }

        if (is_array($trace) and isset($trace[0]) and is_array($trace[0]) and
            isset($trace[0]['line']) and is_int($trace[0]['line'])) {

            $line = $trace[0]['line'];

        } else {

            throw new InvalidArgumentException(
                'バックトレース配列が間違っています', 3
            );
        }

        if (!defined($labelName)) {

            define($labelName, $line + $correctedLine);
        }

        if ($_this instanceof Label) {

            $_this->setLabel($labelName, $line + $correctedLine);
        }
    }

    /**
     * インスタンス内部にラベル作成
     *
     * @api
     * @param string $name ラベル名称
     * @param int $correctLine ラベルが指し示す場所
     */
    public function setLabel($name, $correctLine)
    {
        $this->label[$name] = (int)$correctLine;
    }

    /**
     * ラベル参照
     *
     * マジックメソッドを用い、プロパティ読み込み形式でラベルを参照する
     *
     * @internal
     * @param string $name ラベル名称
     * @return int ラベル行
     * @throws \LogicException 存在しないラベルを参照した
     */
    public function __get($name)
    {
        if (array_key_exists($name, $this->label)) {

            return $this->label[$name];
        }

        throw new  LogicException('存在しないラベルです');
    }

    /**
     * メソッド呼び出し形式でラベル作成
     *
     * マジックメソッドを用い、メソッド呼び出し形式でラベル作成する
     *
     * @internal
     * @param string $name ラベル名称
     * @param array $arguments メソッド呼び出し事の引数で第一引数に行補正
     * @throws \InvalidArgumentException
     */
    public function __call($name, $arguments)
    {
        $trace = debug_backtrace();

        if (array_key_exists(0, $arguments)) {

            self::makeLabel($name, $arguments[0], $trace, $this);

        } else {

            self::makeLabel($name, self::$correctedLine, $trace, $this);
        }
    }

    /**
     * 静的メソッド呼び出し形式でラベル作成
     *
     * マジックメソッドを用い、静的メソッド呼び出し形式でラベル作成する
     *
     * @internal
     * @param string $name ラベル名称
     * @param array $arguments メソッド呼び出し事の引数で第一引数に行補正
     * @throws \InvalidArgumentException
     */
    public static function __callStatic($name, $arguments)
    {
        $trace = debug_backtrace();

        if (array_key_exists(0, $arguments)) {

            self::makeLabel($name, $arguments[0], $trace);

        } else {

            self::makeLabel($name, self::$correctedLine, $trace);
        }
    }
}
API documentation generated by ApiGen