timefrontiers/php-core 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

timefrontiers/php-core

Composer 安装命令:

composer require timefrontiers/php-core

包简介

Core utilities, enums, and helpers for TimeFrontiers packages

README 文档

README

Core utilities, enums, and helpers for TimeFrontiers packages.

PHP Version License

Installation

composer require timefrontiers/php-core

Requirements

  • PHP 8.1+
  • ext-curl (for URL utilities)
  • giggsey/libphonenumber-for-php ^8.13 (for Phone utilities — installed automatically)

Package Contents

Class Description
AccessRank Enum for user access levels (int-backed)
AccessGroup Enum for user access groups (string-backed)
HttpStatus Enum for HTTP status codes
Http HTTP utilities (redirect, JSON responses, headers)
Header HTTP header utilities (status, redirects, caching)
Client HTTP client using cURL
Request Request parameter handling with validation
Url URL manipulation utilities
Str String utilities
Time Date/time utilities
Phone Phone number parsing, formatting, country/continent lookup

AccessRank Enum

User access levels for permission control and error visibility filtering.

use TimeFrontiers\AccessRank;

// Get rank
$rank = AccessRank::USER;
echo $rank->value;  // 1
echo $rank->label(); // "User"

// Compare ranks
if ($user_rank->atLeast(AccessRank::MODERATOR)) {
  // User is staff or higher
}

// Check capabilities
$rank->isStaff();     // true for MODERATOR+
$rank->isTechnical(); // true for DEVELOPER+
$rank->isAdmin();     // true for ADMIN+

// Error visibility
if ($rank->canSee($error_min_rank)) {
  // User can see this error
}

// Get all options (for dropdowns)
$options = AccessRank::options();
// [0 => 'Guest', 1 => 'User', ...]

Rank Values

Rank Value Description
GUEST 0 Public users
USER 1 Logged in users
ANALYST 2 Data analysts
ADVERTISER 3 Advertisers
MODERATOR 4 Staff (internal errors)
EDITOR 5 Content editors
ADMIN 6 Administrators
DEVELOPER 7 Developers (system errors)
SUPERADMIN 8 Super admins (debug errors)
OWNER 14 Full access

AccessGroup Enum

String-backed version of AccessRank for database storage.

use TimeFrontiers\AccessGroup;
use TimeFrontiers\AccessRank;

// Get group
$group = AccessGroup::USER;
echo $group->value;      // "USER"
echo $group->label();    // "User"
echo $group->rankValue(); // 1

// Convert between rank and group
$rank = $group->toRank();              // AccessRank::USER
$group = AccessGroup::fromRank($rank); // AccessGroup::USER

// Check capabilities (same as AccessRank)
$group->isStaff();     // true for MODERATOR+
$group->isTechnical(); // true for DEVELOPER+
$group->isAdmin();     // true for ADMIN+

// Compare groups
if ($group->atLeast(AccessGroup::ADMIN)) {
  // User is admin or higher
}

// Get all options (for dropdowns)
$options = AccessGroup::options();
// ['GUEST' => 'Guest', 'USER' => 'User', ...]

HttpStatus Enum

HTTP status codes with helper methods.

use TimeFrontiers\Http\HttpStatus;

// Use status code
$status = HttpStatus::NOT_FOUND;
echo $status->value;   // 404
echo $status->phrase(); // "Not Found"
echo $status->line();   // "404 Not Found"

// Send as header
$status->send();

// Check status type
$status->isSuccess();     // 2xx
$status->isRedirect();    // 3xx
$status->isClientError(); // 4xx
$status->isServerError(); // 5xx
$status->isError();       // 4xx or 5xx

// Get from code
$status = HttpStatus::fromCode(500);

Http Utilities

use TimeFrontiers\Http\Http;
use TimeFrontiers\Http\HttpStatus;

// Redirect (exits)
Http::redirect('/dashboard');
Http::redirect('/login', HttpStatus::SEE_OTHER);

// JSON responses (exit)
Http::json(['user' => $user]);
Http::success($data, 'User created');
Http::error('Validation failed', HttpStatus::BAD_REQUEST, $errors);
Http::jsonp($data, 'myCallback');              // JSONP (callback-wrapped JSON)

// Build a response body without sending it (middleware / controller returns)
$body = Http::buildResponse(
  success: true,
  message: 'User created',
  data: $user,
  meta: ['request_id' => $id]
);

// Request info
$ip = Http::clientIp();
$method = Http::method();
$url = Http::currentUrl();

// Check request type
Http::isMethod('POST');
Http::isAjax();
Http::isSecure();
Http::accepts('application/json');

// Headers
$auth = Http::header('Authorization');
$headers = Http::headers();
Http::setHeader('X-Custom', 'value');

// CORS
Http::cors('https://example.com', ['GET', 'POST']);

// Disable caching
Http::noCache();

Request Handling

use TimeFrontiers\Http\Request;

// Create from different sources
$request = Request::fromPost();
$request = Request::fromGet();
$request = Request::fromJson();
$request = Request::fromArray($data);

// Get parameters
$email = $request->get('email');
$page = $request->get('page', 1);
$request->has('email'); // true/false

// Filter parameters
$allowed = $request->only(['name', 'email', 'phone']);
$filtered = $request->except(['password', 'token']);

// Validate parameters
$columns = [
  'email' => ['Email', 'email'],
  'name' => ['Name', 'text', 2, 100],
  'age' => ['Age', 'int', 18, 120],
];

$required = ['email', 'name'];

$params = $request->validate($columns, $required);

if ($params === false) {
  $errors = $request->getErrors();
}

// CSRF protection
Request::csrfField('contact_form'); // Returns HTML input

// In form handler:
$token = $request->get('csrf_token');
if (!$request->verifyCSRF('contact_form', $token)) {
  $errors = $request->getErrors();
}

Http Client

cURL-based HTTP client for making API requests.

use TimeFrontiers\Http\Client;

// Create client
$client = new Client('https://api.example.com');

// Or configure manually
$client = Client::create()
  ->setBaseUrl('https://api.example.com')
  ->setHeaders(['Authorization' => 'Bearer token'])
  ->setTimeout(30)
  ->verifySsl(true);

// GET request
$response = $client->get('/users', ['page' => 1]);

// POST with form data
$response = $client->post('/users', ['name' => 'John', 'email' => 'john@example.com']);

// POST with JSON body
$response = $client->postJson('/users', ['name' => 'John']);

// PUT/PATCH/DELETE
$response = $client->putJson('/users/1', ['name' => 'Jane']);
$response = $client->patchJson('/users/1', ['status' => 'active']);
$response = $client->delete('/users/1');

// Handle response
if ($response->isSuccess()) {
  $data = $response->json();
  $name = $response->get('data.user.name');
} else {
  $error = $response->get('error');
  $code = $response->statusCode();
}

// Response methods
$response->isOk();          // true if 200
$response->isSuccess();     // true if 2xx
$response->isError();       // true if 4xx or 5xx
$response->isJson();        // true if JSON content type
$response->body();          // raw body string
$response->json();          // decoded JSON
$response->header('Content-Type');
$response->throwIfError();  // throws on error

Http Header

HTTP header utilities for responses.

use TimeFrontiers\Http\Header;
use TimeFrontiers\Http\HttpStatus;

// Send status and exit
Header::send(HttpStatus::OK);
Header::send(404);

// Redirects
Header::redirect('/dashboard');
Header::redirect('/login', 'Please log in first');
Header::refresh('/dashboard', 5, 'Redirecting in 5 seconds...');

// Error pages (exit)
Header::notFound();
Header::badRequest();
Header::unauthorized();
Header::forbidden();
Header::internalError();

// Error pages with redirect to /app/{code}
Header::notFound(redirect: true, message: 'Page not found');

// Authentication
Header::authDialog('Admin Area', 'Access denied');

// Caching
Header::noCache();
Header::cache(3600);          // 1 hour private cache
Header::cache(86400, true);   // 1 day public cache

// Content headers
Header::contentType('application/pdf');
Header::contentLength(1024);
Header::download('report.pdf');
Header::language('en');

// Security headers
Header::security();  // Common security headers
Header::hsts();      // Strict-Transport-Security
Header::csp([
  'default-src' => "'self'",
  'script-src' => "'self' 'unsafe-inline'",
]);

// Custom headers
Header::set('X-Custom', 'value');
Header::setCustom('Request-Id', '123');  // X-TFr-Request-Id
Header::poweredBy('TimeFrontiers');

// Get custom X-TFr headers from response
$custom = Header::getCustom();           // All X-TFr headers
$value = Header::getCustom('Request-Id');

Time (Date/Time Utilities)

Date and time formatting and manipulation.

use TimeFrontiers\Time;

// Current time
Time::now();        // "2024-01-15 14:30:00" (MySQL format)
Time::today();      // "2024-01-15"
Time::timestamp();  // Unix timestamp

// Formatting
Time::format('Y-m-d', '2024-01-15 14:30:00');
Time::day('2024-01-15');      // "15th"
Time::month('2024-01-15');    // "January"
Time::month('2024-01-15', true); // "Jan"
Time::year('2024-01-15');     // "2024"
Time::weekday('2024-01-15');  // "Monday"
Time::week('2024-01-15');     // 3 (week of year)

// Combined formats
Time::monthDay('2024-01-15');      // "January 15th"
Time::mdy('2024-01-15');           // "January 15th, 2024"
Time::hms('2024-01-15 14:30:00');  // "14:30:00"
Time::hm('2024-01-15 14:30:00');   // "14:30"
Time::hm('...', true);             // "2:30 PM" (12-hour)
Time::datetime('2024-01-15 14:30:00'); // "January 15th, 2024 at 14:30:00"
Time::weekDatetime('2024-01-15');  // "Monday, 15th January 2024"

// Relative time
Time::relative('2024-01-14');     // "1 day ago"
Time::relative('2024-01-20');     // "in 5 days"

// Calculations
Time::add('P1D');                 // Add 1 day
Time::add('PT2H', '2024-01-15');  // Add 2 hours
Time::sub('P1M');                 // Subtract 1 month
Time::diff('2024-01-01', '2024-01-15'); // DateInterval
Time::diffSeconds('2024-01-01', '2024-01-15'); // Seconds

// Comparisons
Time::isPast('2024-01-01');       // true
Time::isFuture('2025-01-01');     // true
Time::isToday('2024-01-15');      // true/false
Time::isSameDay('...', '...');    // true/false

// Conversion
Time::toTimestamp('2024-01-15');  // Unix timestamp
Time::toDateTime('2024-01-15');   // DateTime object
Time::toMysql(1705320600);        // MySQL datetime
Time::toIso('2024-01-15');        // ISO 8601 format

URL Utilities

use TimeFrontiers\Url;

// Add/update query parameters
$url = Url::withParams('/search', ['q' => 'test', 'page' => 2]);
// "/search?q=test&page=2"

// Remove parameters
$url = Url::withoutParams($url, ['page']);
// "/search?q=test"

// Get parameters
$query = Url::getParam($url, 'q');       // "test"
$params = Url::getParams($url);          // ['q' => 'test']

// Check URL status
Url::exists('https://example.com');      // true/false (200 only)
Url::isAccessible('https://example.com'); // true/false (2xx/3xx)
$code = Url::getStatusCode('https://example.com');

// Parse and build
$parts = Url::parse('https://user:pass@example.com:8080/path?q=1#hash');
$url = Url::build($parts);

// Validation
Url::isValid('https://example.com'); // true
Url::getDomain('https://example.com/path'); // "example.com"
Url::normalize('example.com'); // "https://example.com"

String Utilities

use TimeFrontiers\Str;

// Parse email with name
$parsed = Str::parseEmailName('John Doe <john@example.com>');
// ['name' => 'John', 'surname' => 'Doe', 'email' => 'john@example.com']

// File extension
Str::fileExtension('document.pdf');           // "pdf"
Str::fileExtension('image.jpg?v=123');        // "jpg"

// Base64
Str::isBase64('SGVsbG8gV29ybGQ=');             // true
Str::base64Decode('SGVsbG8gV29ybGQ=');         // "Hello World"

// Slugify
Str::slug('Hello World!');                     // "hello-world"
Str::slug('Hello World!', '_');                // "hello_world"

// Truncate
Str::truncate('Long text here', 10);           // "Long te..."
Str::truncateWords('Long text here', 10);      // "Long..."
Str::limitWords('One two three four', 2);      // "One two..."

// Case conversion
Str::toCamelCase('hello_world');               // "helloWorld"
Str::toPascalCase('hello_world');              // "HelloWorld"
Str::toSnakeCase('helloWorld');                // "hello_world"
Str::toKebabCase('helloWorld');                // "hello-world"

// Masking
Str::mask('4111111111111111', 4, 4);           // "4111********1111"

// String checks
Str::contains('Hello World', 'World');         // true
Str::startsWith('Hello World', 'Hello');       // true
Str::endsWith('Hello World', 'World');         // true

// Word count
Str::wordCount('Hello World');                 // 2

// Excerpt (strips HTML, normalizes whitespace, truncates at word boundary)
Str::excerpt('<p>Long <b>article</b> text goes here...</p>', 30);
// "Long article text goes here..."

// Excerpt window around a phrase
Str::excerptAround('Long text with keyword here', 'keyword', 10);
// "...with keyword her..."

// Chunk a string (e.g., split a code into groups)
Str::chunk('1234567890', 3, '-');              // "123-456-789-0"

// Pattern replacement
Str::patternReplace(
  ['{{name}}' => '{{name}}', '{{date}}' => '{{date}}'],
  ['{{name}}' => 'John', '{{date}}' => '2024-01-15'],
  'Hello {{name}}, today is {{date}}'
);
// "Hello John, today is 2024-01-15"

Need random strings? Use TimeFrontiers\Data\Random from timefrontiers/php-data — it's CSPRNG-backed with alphanumeric, hex, base64, uuid, numeric, and more. Str::random no longer exists in php-core.

Phone Utilities

Static wrapper around giggsey/libphonenumber-for-php for parsing, validating, formatting, and geolocating phone numbers. Every method returns null (or false for is* checks) on failure — no exceptions thrown.

use TimeFrontiers\Phone;

Formatting

Phone::toE164('08031234567', 'NG');        // "+2348031234567"
Phone::toIntl('+2348031234567');           // "+234 803 123 4567"
Phone::toNational('+2348031234567');       // "0803 123 4567"
Phone::toLocal('+2348031234567');          // alias of toNational()
Phone::toRfc3966('+2348031234567');        // "tel:+234-803-123-4567"

// Generic formatter
Phone::format('08031234567', Phone::FORMAT_E164, 'NG');

Country & continent lookup

Phone::country('+2348031234567');      // "NG"
Phone::countryName('+2348031234567');  // "Nigeria"
Phone::dialCode('+2348031234567');     // 234
Phone::continent('+2348031234567');    // "Africa"

// Skip the phone step if you already have the ISO code:
Phone::continentFromCountry('JP');     // "Asia"
Phone::continentFromCountry('BR');     // "South America"

Supported continents: Africa, Asia, Europe, North America, South America, Oceania, Antarctica. The internal map covers all 249 ISO 3166-1 alpha-2 codes.

Line type & carrier

Phone::type('+2348031234567');         // "mobile"
Phone::type('+442071838750');          // "landline"
Phone::type('+18005551234');           // "toll_free"

Phone::carrier('+2348031234567');      // "MTN" (mobile only)
Phone::location('+2348031234567');     // "Nigeria" / "Lagos" (locale-dependent)
Phone::timeZones('+2348031234567');    // ["Africa/Lagos"]

Possible type() values: mobile, landline, fixed_or_mobile, toll_free, premium_rate, shared_cost, voip, personal_number, pager, uan, voicemail, unknown.

Validation

Phone::isValid('+2348031234567');          // true
Phone::isValid('08031234567', 'NG');       // true
Phone::isValid('12345');                   // false

Phone::isPossible('+2348031234567');       // true — length-only check
Phone::isRegion('+2348031234567', 'NG');   // true

Structured parse

One call returning everything at once — handy for logging or API responses:

Phone::parse('08031234567', 'NG');
// [
//   'valid'        => true,
//   'possible'     => true,
//   'country'      => 'NG',
//   'country_name' => 'Nigeria',
//   'continent'    => 'Africa',
//   'dial_code'    => 234,
//   'national'     => '0803 123 4567',
//   'e164'         => '+2348031234567',
//   'intl'         => '+234 803 123 4567',
//   'rfc3966'      => 'tel:+234-803-123-4567',
//   'type'         => 'mobile',
//   'carrier'      => 'MTN',
//   'location'     => 'Nigeria',
//   'time_zones'   => ['Africa/Lagos'],
// ]

Normalization

Cheap, no libphonenumber needed — useful as a pre-store cleanup:

Phone::normalize(' +234 (803) 123-4567 ');  // "+2348031234567"
Phone::normalize('0803.123.4567');          // "08031234567"

License

MIT License

timefrontiers/php-core 适用场景与选型建议

timefrontiers/php-core 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 28 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 15 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「php」 「helpers」 「phone」 「utilities」 「core」 「enums」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 timefrontiers/php-core 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 timefrontiers/php-core 我们能提供哪些服务?
定制开发 / 二次开发

基于 timefrontiers/php-core 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 28
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 33
  • 依赖项目数: 5
  • 推荐数: 1

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-15