Download the PHP package yangweijie/perry-php without Composer

On this page you can find all versions of the php package yangweijie/perry-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package perry-php

Perry PHP

Cross-platform UI abstraction and code generation framework. Define UI once in PHP, generate native code for Apple, Android, Windows, Linux, and Web platforms.


Table of Contents


Installation

Requirements: PHP 8.2+


Quick Start


UI Components

All components extend Perry\UI\Widget. Each widget has:


Text

Displays static text or reactive bound data.

Constructor:

Parameter Type Description
$content string\|Binding Static string or a Binding for reactive display

Methods:

Method Returns Description
content() string Text content (empty string if bound)
getBinding() ?Binding The bound Binding, or null for static text

How bindings work: When a Text widget receives a Binding, AppContainer::bindings() auto-collects it. The backend generates @State (Swift), const state = {} (JS), or mutableStateOf (Kotlin) for it.

Generated code:

Full example — a live clock display:


Button

Clickable button with label and optional action.

Constructor:

Parameter Type Default Description
$label string Button text
$action Action\|\Closure\|null null Click handler

Methods:

Method Returns Description
label() string Button label text
getAction() ?Action Action object

Generated code (Swift):

Generated code (HTML):


VStack

Vertical layout — arranges children top to bottom.

Constructor:

Parameter Type Description
...$children Widget Child widgets (variadic)

Spacing: Controlled via Style::padding() on the VStack — the padding value becomes spacing in SwiftUI:

Generated code:


HStack

Horizontal layout — arranges children left to right.

Constructor:

Parameter Type Description
...$children Widget Child widgets (variadic)

Generated code:


Spacer

Flexible space that expands to fill available area. Use inside HStack or VStack to push elements apart.

Constructor: No parameters.

Generated code:


Image

Displays an image from a path or resource name.

Constructor:

Parameter Type Description
$source string Image path or asset name

Methods:

Method Returns Description
source() string Image source path

Generated code:


ScrollView

Scrollable container for content that exceeds the viewport.

Constructor:

Parameter Type Description
...$children Widget Child widgets inside scroll area

Generated code:


TextInput

Text input field with placeholder.

Constructor:

Parameter Type Default Description
$value StateId State variable bound to input
$placeholder string '' Placeholder text

Methods:

Method Returns Description
value() StateId Bound state ID
placeholder() string Placeholder text

Generated code:


Toggle

Toggle switch with label.

Constructor:

Parameter Type Default Description
$isOn StateId State variable bound to toggle
$label string '' Toggle label

Methods:

Method Returns Description
isOn() StateId Bound state ID
label() string Label text

Generated code:


AppContainer

Root application container. Wraps your widget tree, sets window dimensions, and auto-collects all Binding objects.

Constructor:

Parameter Type Default Description
$content Widget Root widget tree
$windowWidth ?int null Window width in pixels
$windowHeight ?int null Window height in pixels
...$extraBindings Binding Additional state bindings

Methods:

Method Returns Description
content() Widget Root widget
windowWidth() ?int Window width
windowHeight() ?int Window height
bindings() Binding[] All collected bindings

Binding collection logic: AppContainer walks the entire widget tree and collects every Binding from Text widgets. Bindings passed as ...$extraBindings are also included. This is how the backends know which @State / const state variables to declare.


State Management

Binding

Declarative, two-way data binding. The primary way to manage state.

Constructor:

Parameter Type Description
$name string Variable name in generated code
$initialValue mixed Default value (string, int, float, bool)

How it works:

  1. Pass a Binding to a Text widget: new Text($display)
  2. AppContainer auto-collects it
  3. Backends generate state declarations:
    • Swift: @State private var display = "0"
    • JavaScript: const state = { display: "0" }
    • Kotlin: var display = mutableStateOf("0")
    • Dart: var display = ValueNotifier("0")
    • C#: var display = "0";
  4. When a button action modifies $display, the generated code assigns to the state variable
  5. Re-render updates all bound Text widgets

Using $count in actions (closure):


State / StateId

Lower-level state management for TextInput and Toggle widgets.

When to use:


Actions

Simple Actions

Pre-built action types for common operations:

Widget Actions

Interactive widgets support Action for event handling:

Supported event properties:

Widget Event Property Description
Button action (constructor) Fires on click/tap
Slider onChange Fires when value changes
TextInput onChange Fires when text changes
Toggle onToggle Fires when checked state changes

Action types work across all widgets:

ActionType Button Slider TextInput Toggle
SetValue
Append
Clear
Custom
Closure

Closure Actions

The most powerful action type. Write PHP closures that get parsed into an AST and cross-compiled to any target language.

How it works:

Closure bindings (parameter substitution):

Nested closure pattern (for parameterized buttons):


Supported PHP Features

Feature Swift JavaScript Kotlin Dart C#
Variables var x let x var x var x var x
State vars x = ... state.x = ... x.value = ... x.value = ... x = ...
If/else if {} else {} if {} else {} if {} else {} if {} else {} if {} else {}
While while {} while {} while {} while {} while {}
For for {} for {} for {} for {} for {}
Foreach for x in y for x of y for x in y for x in y foreach x in y
Ternary c ? a : b c ? a : b if (c) a else b c ? a : b c ? a : b
Switch switch {} switch {} when {} switch {} switch {}
Match match {} switch+return when-> switch+IIFE switch expr
Try/catch do{}catch{} try{}catch{} try{}catch{} try{}catch{} try{}catch{}
Throw throw throw throw throw throw
Type cast Int(), Double() parseInt(), parseFloat() .toInt(), .toDouble() int.parse(), double.parse() (int), (double)
Increment += 1 x++ x++ x++ x++
Compound assign +=, -=, *=, /= +=, -=, *=, /= +=, -=, *=, /= +=, -=, *=, /= +=, -=, *=, /=
Nullsafe ?.method() ?.method() ?.method() ?.method() ?.method()
Static call Class.method() Class.method() Class.method() Class.method() Class.method()

PHP Function Mappings

PHP Swift JavaScript Kotlin Dart C#
substr($s, -1) String(s.last!) s.slice(-1) s.last().toString() s[s.length-1] s[s.Length-1]
substr($s, 0, -1) String(s.dropLast(1)) s.slice(0,-1) s.dropLast(1) s.substring(0,s.length-1) s.Substring(0,s.Length-1)
substr($s, 1) String(s.dropFirst(1)) s.slice(1) s.dropFirst(1) s.substring(1) s.Substring(1)
strlen($s) s.count s.length s.length s.length s.Length
floatval($x) Double(x) ?? 0 parseFloat(x) x.toDoubleOrNull() ?: 0.0 double.parse(x.toString()) Convert.ToDouble(x)
intval($x) Int(x) parseInt(x) x.toIntOrNull() ?: 0 int.parse(x.toString()) Convert.ToInt32(x)
strval($x) String(x) String(x) x.toString() x.toString() x.ToString()
in_array($x, $a) a.contains(x) a.includes(x) a.contains(x) a.contains(x) a.Contains(x)
strpos($s, $n) s.firstIndex(of: n) IIFE with indexOf s.indexOf(n) s.indexOf(n) s.IndexOf(n)
end($a) a.last! a[a.length-1] a.last() a.last a[a.Length-1]
number_format($n,$d) String(format: "%.$df", $n) n.toFixed(d) String.format("%.$df",n) n.toStringAsFixed(d) $n.ToString("F$d")
floor($x) floor(x) Math.floor(x) Math.floor(x).toInt() x.floor() Math.Floor(x)
empty($x) x.isEmpty !x x.isEmpty() x.isEmpty string.IsNullOrEmpty(x)
count($a) a.count a.length a.size a.length a.Length
preg_split('/[...]/', $s) s.components(separatedBy:) s.split(/regex/) s.split().toRegex() s.split(RegExp(...)) Regex.Split(s,...)

=== false optimization: All generators detect expr === false and emit !expr instead.


Styling

Style Builder

Fluent API — chain methods to compose styles:

Methods:

Method Parameters Description
make() Create new Style
set(StyleProperty, $value) enum, mixed Set any property
get(StyleProperty) enum Get property value
has(StyleProperty) enum Check if property is set
all() Get all properties
merge(Style) Style Merge another style (right wins)
backgroundColor(hex) string Background color
foregroundColor(hex) string Text/icon color
fontSize(float) float Font size in points
fontWeight(string) string Font weight ('bold', 'light', etc.)
textAlignment(string) string Text alignment ('center', 'left', 'right')
padding(float) float Uniform padding
paddingAll(top, bottom, leading, trailing) float×4 Individual padding
width(float) float Fixed width
height(float) float Fixed height
cornerRadius(float) float Corner radius
opacity(float) float Opacity (0.0–1.0)
border(width, color) float, string Border width + color
shadow(color, radius, offsetX, offsetY) string, float×3 Drop shadow

Style Properties Reference

Property Enum Type Description
Background Color StyleProperty::BackgroundColor string Background color (hex)
Foreground Color StyleProperty::ForegroundColor string Text/icon color (hex)
Border Color StyleProperty::BorderColor string Border color (hex)
Border Width StyleProperty::BorderWidth float Border width
Corner Radius StyleProperty::CornerRadius float Corner rounding
Opacity StyleProperty::Opacity float Transparency (0–1)
Padding StyleProperty::Padding float Uniform padding
Padding Top StyleProperty::PaddingTop float Top padding
Padding Bottom StyleProperty::PaddingBottom float Bottom padding
Padding Leading StyleProperty::PaddingLeading float Left padding
Padding Trailing StyleProperty::PaddingTrailing float Right padding
Margin StyleProperty::Margin float Uniform margin
Width StyleProperty::Width float Fixed width
Height StyleProperty::Height float Fixed height
Font Size StyleProperty::FontSize float Font size
Font Weight StyleProperty::FontWeight string Font weight
Font Family StyleProperty::FontFamily string Font family
Text Alignment StyleProperty::TextAlignment string Text alignment
Shadow Color StyleProperty::ShadowColor string Shadow color
Shadow Radius StyleProperty::ShadowRadius float Shadow blur
Shadow Offset X StyleProperty::ShadowOffsetX float Shadow X offset
Shadow Offset Y StyleProperty::ShadowOffsetY float Shadow Y offset
Text Decoration StyleProperty::TextDecoration string Text decoration
Line Spacing StyleProperty::LineSpacing float Line spacing
Min Width StyleProperty::MinWidth float Minimum width
Min Height StyleProperty::MinHeight float Minimum height
Max Width StyleProperty::MaxWidth float Maximum width
Max Height StyleProperty::MaxHeight float Maximum height

Platform Support Matrix

All 6 backends now support the full set of 28 StyleProperties and event system (Button/Slider/TextInput/Toggle Actions):

Feature macOS (SwiftUI) iOS (SwiftUI) Android (XML) Android (Compose) Web (HTML) Linux (Gtk4) Windows (WinUI)
StyleProperties
BackgroundColor
ForegroundColor
BorderWidth/BorderColor
CornerRadius
Padding (all edges)
Margin (all edges)
Width / Height
FontSize / FontWeight / FontFamily
TextAlignment
Shadow (color/radius/offset)
TextDecoration
LineSpacing
Min/Max Width/Height
Opacity
Event System
Button action (Click)
Slider onChange
TextInput onChange
Toggle onToggle
Widgets
Slider / TextInput / Toggle
NavigationView / TabView
List

Support levels:

Level Description
Wired Fully supported, generates native code
Stub Stub implementation (tvOS, visionOS, watchOS)
Missing Not yet implemented
NotApplicable Not applicable for this platform

Code Generation

Backends

Backend Class Platforms Output
swiftui SwiftUIBackend macOS, iOS, tvOS, visionOS, watchOS SwiftUI Swift
html HtmlBackend Web, WebAssembly HTML/CSS/JavaScript
compose ComposeBackend Android Jetpack Compose Kotlin
android-xml AndroidXmlBackend Android Android XML layouts
winui WinUIBackend Windows WPF/WinUI XAML
gtk4 Gtk4Backend Linux GTK4 XML UI

Generators

Generators transform IR into target language code. Each implements Perry\IR\Generator.

Generator Language State Var New Var
SwiftGenerator Swift name = ... var name = ...
JavaScriptGenerator JavaScript state.name = ... let name = ...
KotlinGenerator Kotlin name.value = ... var name = ...
DartGenerator Dart name.value = ... var name = ...
CSharpGenerator C# name = ... var name = ...

IR System

54 intermediate representation node types:

Core (14): Program, Assignment, IfStatement, BinaryOp, UnaryOp, Variable, Literal, FunctionCall, ReturnStatement, ArrayAccess, MethodCall, PropertyAccess, Ternary, ArrayLiteral

Loops (5): WhileStatement, ForStatement, ForeachStatement, BreakStatement, ContinueStatement

Switch/Match (3): SwitchStatement, CaseNode, MatchExpression

Output (2): EchoStatement, PrintStatement

Type System (1): Cast

Inc/Dec (2): Increment, Decrement

Compound Assignment (5): PlusAssign, MinusAssign, MulAssign, DivAssign, ModAssign

Binary Ops (11): PowOp, BitwiseAnd, BitwiseOr, BitwiseXor, ShiftLeft, ShiftRight, SpaceshipOp, CoalesceOp, LogicalAnd, LogicalOr, LogicalXor

Unary Ops (2): UnaryPlus, BitwiseNot

Nullsafe (2): NullsafeMethodCall, NullsafePropertyAccess

Exceptions (3): ThrowStatement, TryCatchStatement, CatchClause

Static (3): StaticCall, StaticPropertyAccess, ClassConstFetch

Include (1): IncludeStatement


Platform Support

Platform Target String Backend
macOS macos swiftui
iOS ios swiftui
iOS Simulator ios-simulator swiftui
tvOS tvos swiftui
visionOS visionos swiftui
watchOS watchos swiftui
Android android compose / android-xml
Linux gtk4-linux gtk4
Windows windows winui
Web web html
WebAssembly wasm html

Build System

Compile to native app:

Windows Requirements

Apps that use the WebView widget (e.g., the Pry JSON viewer) require WebView2 Runtime on Windows.

Install WebView2 Runtime:

Build output: The compiler writes pry.html alongside the .exe file. The app reads it at runtime via WebView2's NavigateToString().


CLI Usage


Examples

Calculator

Full calculator with 7 actions, state management, and styling. Runs on macOS and web.

Simple Counter

Todo List

Pry — JSON Viewer (with WebView2 on Windows)

A native JSON viewer with tree view, search, syntax highlighting, and clipboard support. Uses WebView widget to embed a full HTML/JS UI.

Note for Windows: Requires WebView2 Runtime. The generated pry.html file contains the complete viewer UI (tree rendering, search, context menus) and is loaded at runtime.


Extending Perry

1. Adding a Custom Widget

Create a new widget class, add it to WidgetKind, and update all backends to handle it.

Step 1: Create the widget class

Step 2: Add enum case to WidgetKind

Step 3: Update each backend to generate code for Slider

Step 4: Repeat for each backend (KotlinGenerator, DartGenerator, CSharpGenerator, etc.)


2. Adding a Custom Backend

A backend converts the widget tree into target platform code.

Step 1: Create the backend class

Step 2: Register in CodegenFactory

Step 3: Use it


3. Adding a Custom Generator

A generator converts IR nodes into target language code.

Step 1: Create the generator class

Step 2: Use it with a backend


4. Adding PHP Function Mappings

Each generator maps PHP built-in functions to target language equivalents.

Example: Add array_map() support to SwiftGenerator

To add support across all generators:

  1. Add the mapping in SwiftGenerator.php
  2. Add the mapping in JavaScriptGenerator.php
  3. Add the mapping in KotlinGenerator.php
  4. Add the mapping in DartGenerator.php
  5. Add the mapping in CSharpGenerator.php
  6. Add tests in tests/Generator/

Architecture


License

MIT


All versions of perry-php with dependencies

PHP Build Version
Package Version
Requires php Version >=8.2
ext-json Version *
nikic/php-parser Version ^5.7
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package yangweijie/perry-php contains the following files

Loading the files please wait ...