— No reviews yet
0 installs
18 views
0.0% view→install
Install
$ agentstack add skill-miles990-claude-software-skills-php ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Are you the author of Php? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claimAbout
PHP
Overview
Modern PHP (7.4+/8.x) patterns including typed properties, attributes, and modern OOP features.
Modern PHP Features
Type System
id = uniqid();
$this->createdAt = new DateTimeImmutable();
}
}
// Union types (PHP 8.0+)
function process(string|int $value): string|int
{
return is_string($value) ? strtoupper($value) : $value * 2;
}
// Intersection types (PHP 8.1+)
function processIterable(Countable&Iterator $items): int
{
return count($items);
}
// Return types
function findUser(string $id): ?User
{
return $this->repository->find($id);
}
function getUsers(): array
{
return $this->repository->findAll();
}
// Never return type (PHP 8.1+)
function fail(string $message): never
{
throw new RuntimeException($message);
}
// Nullable types
function setName(?string $name): void
{
$this->name = $name;
}
Attributes (PHP 8.0+)
userService->getAll();
}
#[Route(path: '/users/{id}', method: 'GET')]
public function show(string $id): User
{
return $this->userService->find($id);
}
}
// Reading attributes
$reflection = new ReflectionClass(User::class);
$attributes = $reflection->getAttributes(Entity::class);
foreach ($attributes as $attribute) {
$instance = $attribute->newInstance();
echo $instance->table; // 'users'
}
Enums (PHP 8.1+)
'Pending Review',
self::Active => 'Active',
self::Inactive => 'Inactive',
};
}
}
// Backed enum (with values)
enum Role: string
{
case Admin = 'admin';
case Moderator = 'moderator';
case User = 'user';
public function permissions(): array
{
return match ($this) {
self::Admin => ['read', 'write', 'delete', 'admin'],
self::Moderator => ['read', 'write', 'delete'],
self::User => ['read', 'write'],
};
}
public static function fromString(string $value): self
{
return self::from($value);
}
public static function tryFromString(string $value): ?self
{
return self::tryFrom($value);
}
}
// Usage
$status = Status::Active;
echo $status->label(); // "Active"
$role = Role::Admin;
echo $role->value; // "admin"
$userRole = Role::from('user');
$permissions = $userRole->permissions();
Object-Oriented Patterns
Traits
createdAt;
}
public function getUpdatedAt(): ?DateTimeImmutable
{
return $this->updatedAt;
}
public function touch(): void
{
$now = new DateTimeImmutable();
$this->createdAt ??= $now;
$this->updatedAt = $now;
}
}
trait SoftDeletable
{
protected ?DateTimeImmutable $deletedAt = null;
public function delete(): void
{
$this->deletedAt = new DateTimeImmutable();
}
public function restore(): void
{
$this->deletedAt = null;
}
public function isDeleted(): bool
{
return $this->deletedAt !== null;
}
}
// Using traits
class Document
{
use Timestampable;
use SoftDeletable;
public function __construct(
public string $title,
public string $content
) {
$this->touch();
}
}
// Trait conflict resolution
trait A
{
public function hello(): string
{
return 'Hello from A';
}
}
trait B
{
public function hello(): string
{
return 'Hello from B';
}
}
class MyClass
{
use A, B {
A::hello insteadof B;
B::hello as helloFromB;
}
}
Interfaces and Abstract Classes
pdo->prepare(
"SELECT * FROM {$this->table} WHERE id = :id"
);
$stmt->execute(['id' => $id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row ? $this->hydrate($row) : null;
}
public function findAll(): array
{
$stmt = $this->pdo->query("SELECT * FROM {$this->table}");
return array_map(
fn(array $row) => $this->hydrate($row),
$stmt->fetchAll(PDO::FETCH_ASSOC)
);
}
}
// Concrete implementation
class UserRepository extends BaseRepository
{
public function __construct(PDO $pdo)
{
parent::__construct($pdo, 'users');
}
protected function hydrate(array $row): User
{
return new User(
id: $row['id'],
email: $row['email'],
name: $row['name']
);
}
public function findByEmail(string $email): ?User
{
// Custom method
}
}
Error Handling
$errors],
$previous
);
}
}
class NotFoundException extends AppException
{
public function __construct(
string $resource,
string $id,
?Throwable $previous = null
) {
parent::__construct(
"{$resource} not found: {$id}",
'NOT_FOUND',
['resource' => $resource, 'id' => $id],
$previous
);
}
}
// Result pattern
readonly class Result
{
private function __construct(
public mixed $value,
public ?string $error,
public bool $success
) {}
public static function success(mixed $value): self
{
return new self($value, null, true);
}
public static function failure(string $error): self
{
return new self(null, $error, false);
}
public function map(callable $fn): self
{
if (!$this->success) {
return $this;
}
return self::success($fn($this->value));
}
public function flatMap(callable $fn): self
{
if (!$this->success) {
return $this;
}
return $fn($this->value);
}
}
// Usage
function createUser(array $data): Result
{
if (empty($data['email'])) {
return Result::failure('Email is required');
}
try {
$user = new User($data['email'], $data['name'] ?? '');
$this->repository->save($user);
return Result::success($user);
} catch (Exception $e) {
return Result::failure($e->getMessage());
}
}
Collections and Arrays
'Alice', 'age' => 30],
['name' => 'Bob', 'age' => 25],
['name' => 'Charlie', 'age' => 35],
];
// Filter
$adults = array_filter($users, fn($u) => $u['age'] >= 30);
// Map
$names = array_map(fn($u) => $u['name'], $users);
// Reduce
$totalAge = array_reduce($users, fn($sum, $u) => $sum + $u['age'], 0);
// Find
$bob = array_filter($users, fn($u) => $u['name'] === 'Bob');
$bob = current($bob); // Get first match
// Sort
usort($users, fn($a, $b) => $a['age'] $b['age']);
// Group by (custom)
function groupBy(array $items, string $key): array
{
return array_reduce($items, function ($groups, $item) use ($key) {
$groups[$item[$key]][] = $item;
return $groups;
}, []);
}
// Collection class
class Collection implements Countable, IteratorAggregate
{
public function __construct(private array $items = []) {}
public static function from(array $items): self
{
return new self($items);
}
public function map(callable $fn): self
{
return new self(array_map($fn, $this->items));
}
public function filter(callable $fn): self
{
return new self(array_filter($this->items, $fn));
}
public function reduce(callable $fn, mixed $initial = null): mixed
{
return array_reduce($this->items, $fn, $initial);
}
public function first(): mixed
{
return $this->items[array_key_first($this->items)] ?? null;
}
public function count(): int
{
return count($this->items);
}
public function getIterator(): Traversable
{
return new ArrayIterator($this->items);
}
public function toArray(): array
{
return $this->items;
}
}
// Usage
$result = Collection::from($users)
->filter(fn($u) => $u['age'] >= 30)
->map(fn($u) => $u['name'])
->toArray();
Dependency Injection
logger->info('Creating user', ['email' => $email]);
$user = new User($email, $name);
$this->repository->save($user);
$this->events->dispatch(new UserCreated($user));
return $user;
}
}
// Simple container
class Container
{
private array $bindings = [];
private array $instances = [];
public function bind(string $abstract, callable $concrete): void
{
$this->bindings[$abstract] = $concrete;
}
public function singleton(string $abstract, callable $concrete): void
{
$this->bindings[$abstract] = function ($c) use ($abstract, $concrete) {
if (!isset($this->instances[$abstract])) {
$this->instances[$abstract] = $concrete($c);
}
return $this->instances[$abstract];
};
}
public function get(string $abstract): mixed
{
if (isset($this->bindings[$abstract])) {
return $this->bindings[$abstract]($this);
}
return $this->resolve($abstract);
}
private function resolve(string $class): object
{
$reflection = new ReflectionClass($class);
$constructor = $reflection->getConstructor();
if (!$constructor) {
return new $class();
}
$params = array_map(
fn(ReflectionParameter $p) => $this->get($p->getType()->getName()),
$constructor->getParameters()
);
return $reflection->newInstanceArgs($params);
}
}
Related Skills
- [[backend]] - Laravel, Symfony
- [[database]] - Doctrine, Eloquent
- [[testing]] - PHPUnit, Pest
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: miles990
- Source: miles990/claude-software-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.