DEV Community

Cover image for WebForms.php 2.1 Released - DeepSeek Converted and Qwen Evaluated
Elanat Framework
Elanat Framework

Posted on

WebForms.php 2.1 Released - DeepSeek Converted and Qwen Evaluated

WebForms.php 2.1 has been released as the PHP back-end implementation of WebForms Core 2.1.

This release is different from a typical porting story.

The PHP implementation was converted from the C# implementation of WebForms Core using DeepSeek, and then independently evaluated with Qwen.

The process was not simply:

C# → PHP

It was:

C# → DeepSeek conversion → manual review → Qwen evaluation → corrections → testing → release

This article explains that process and some of the interesting problems that appeared during the conversion.

What is WebForms.php?

WebForms.php is the PHP back-end part of WebForms Core.

WebForms Core is a server-driven web technology based on the Commander–Executor concept.

The server generates commands that describe UI operations and execution flow. WebFormsJS, running in the browser, interprets and executes those commands.

WebForms Core in PHP

The WebForms class itself does not manipulate the browser DOM directly.

It generates the WebForms Core command structure.

This makes the WebForms class particularly suitable for implementation in multiple programming languages.

The PHP implementation provides the same WebForms Core programming model for PHP applications.

Why Convert the C# Implementation?

WebForms Core already has implementations for multiple programming languages.

The C# implementation is the primary reference implementation and contains a large number of methods for:

  • DOM manipulation
  • event management
  • Fetch operations
  • conditions
  • loops
  • state management
  • storage
  • browser history
  • WebSockets
  • SSE
  • templates
  • selectors
  • Action Controls
  • and other WebForms Core operations

The WebForms class mainly generates command strings.

Because of this architecture, the fundamental logic does not need to be redesigned for every language.

The objective of the PHP implementation was therefore to preserve the behavior and output of the C# implementation while adapting the code to PHP conventions and language capabilities.

DeepSeek Conversion

I provided the C# implementation and related helper classes to DeepSeek.

The instructions were intentionally strict.

DeepSeek was asked to first analyze the structure and explain the conversion approach.

The important requirement was that the conversion should preserve the behavior of the C# implementation.

However, the PHP implementation should not simply look like C# code written with PHP syntax.

The destination language's conventions were explicitly required.

For example, PHP naming conventions should be used where appropriate.

A C# method such as:

SetWidth(...)
Enter fullscreen mode Exit fullscreen mode

should become:

setWidth(...)
Enter fullscreen mode Exit fullscreen mode

and parameters should follow PHP naming conventions:

$inputPlace
$width
Enter fullscreen mode Exit fullscreen mode

rather than preserving C#-style parameter names such as:

$InputPlace
$Width
Enter fullscreen mode Exit fullscreen mode

The same principle applied to language features.

If C# used a feature that did not exist in PHP, the conversion needed to use an appropriate PHP equivalent rather than attempting to reproduce the syntax literally.

Overloading Was One of the Interesting Problems

C# supports method overloading.

PHP does not support traditional method overloading based on parameter signatures in the same way.

Therefore, overloaded C# methods needed to be represented using PHP language features where possible.

For example, instead of creating unnecessary methods for different parameter types, PHP Union Types can be used.

A method can accept:

string|int
Enter fullscreen mode Exit fullscreen mode

and determine the appropriate behavior internally.

For example:

public function setWidth(string $inputPlace, string|int $width): void
{
    if (is_int($width)) {
        $width .= 'px';
    }

    $this->add('sw' . $inputPlace, $width);
}
Enter fullscreen mode Exit fullscreen mode

This keeps the public API compact while preserving the behavior expected from the overloaded C# methods.

Nullable parameters were also handled using PHP's nullable types and default values.

For example:

?int $second = null
Enter fullscreen mode Exit fullscreen mode

can represent an optional second argument when converting an overloaded method such as a random-number operation.

The important point is that the goal was not to reproduce the C# method signatures.

The goal was to preserve their behavior using the capabilities of PHP.

The First Review

After the DeepSeek conversion, the generated code was reviewed manually.

This was necessary because syntactically valid PHP does not necessarily mean behaviorally compatible PHP.

The two languages have important differences in:

  • type conversion
  • null handling
  • method overloading
  • string conversion
  • arrays
  • optional parameters
  • naming conventions
  • object handling

A port can therefore compile and run while still producing a different WebForms Core command.

This is particularly important for WebForms Core because the generated command is effectively part of the protocol between the WebForms class and WebFormsJS.

A small difference in generated output can therefore become a functional difference.

Qwen Evaluation

After the initial conversion, I gave the PHP implementation to Qwen for an independent evaluation.

The purpose was not to ask Qwen to rewrite the entire implementation.

It was asked to evaluate the conversion and look for incompatibilities between the PHP implementation and the original C# behavior.

This produced several useful findings.

Two of them were particularly important.

Issue 1: implode() and Mixed-Type Arguments

The C# implementation could use:

string.Join(US, Args)
Enter fullscreen mode Exit fullscreen mode

where Args could contain objects or values of different types.

C# converts the values to their string representation when joining them.

The corresponding PHP implementation initially used:

implode(self::US, $Args)
Enter fullscreen mode Exit fullscreen mode

This is not equivalent for arbitrary mixed values.

PHP's behavior around non-string values passed to implode() is different, particularly with newer PHP versions.

Qwen therefore identified the need to explicitly convert the values:

implode(
    self::US,
    array_map('strval', $Args)
)
Enter fullscreen mode Exit fullscreen mode

This makes the intended conversion explicit and avoids relying on PHP's implicit behavior.

The important lesson was that a direct API-to-API translation is not always a semantic translation.

The C# expression and the PHP expression may look equivalent while behaving differently with real input types.

Issue 2: null and Empty String Behavior

Another issue involved the internal add() method.

The C# implementation uses StringBuilder.Append().

Appending a null value does not insert the four characters "null" and does not remove the preceding structure. It effectively contributes an empty string.

This distinction matters when generating WebForms Core commands.

The PHP implementation initially treated a null value differently.

For methods such as:

deleteState(?string $path = null)
Enter fullscreen mode Exit fullscreen mode

the generated command could therefore differ from the C# implementation.

Qwen identified this difference and suggested explicitly normalizing the null value:

$this->add('DS', $path ?? '');
Enter fullscreen mode Exit fullscreen mode

The result preserves the command structure expected from the C# implementation.

This was not a syntax error.

Both versions were valid PHP.

It was a cross-language semantic difference.

Other Findings

Qwen also identified several other areas that required attention during the conversion.

These included handling overloaded methods using PHP Union Types, optional and nullable parameters, and type-based routing in helper methods.

For example, the InputPlace::attribute implementation can use the PHP type system to distinguish different forms of the original overloaded API.

Qwen also identified corrections related to specific converted values, including the CPP value in WasmLanguage and the prefix generated by SetMaxLength.

These findings were reviewed against the intended WebForms Core behavior before being incorporated.

The purpose of this process was not to assume that every suggestion from an AI evaluator was automatically correct.

Each finding still had to be compared with the original implementation and the intended protocol.

AI Did Not Replace Testing

This is probably the most important part of this release.

DeepSeek was useful for producing the initial PHP implementation.

Qwen was useful as an independent reviewer.

But neither replaced testing.

The final implementation was reviewed against the original C# implementation and tested for compatibility with WebFormsJS.

This distinction matters.

AI can identify a large number of repetitive transformations very quickly.

It can also identify subtle differences that are easy to miss during manual review.

However, the final authority is still the actual behavior of the software.

The workflow therefore became:

C# Reference Implementation
          ↓
      DeepSeek
          ↓
   PHP Conversion
          ↓
    Manual Review
          ↓
        Qwen
          ↓
 Semantic Corrections
          ↓
       Testing
          ↓
   WebForms.php 2.1
Enter fullscreen mode Exit fullscreen mode

PHP Conventions

One of the goals of the conversion was to make WebForms.php feel like PHP code rather than C# code translated into PHP syntax.

This includes method naming, parameter naming, type declarations, nullable parameters, Union Types, arrays, and other language-specific constructs.

For example, PHP should use:

$inputPlace
$width
$maxValue
Enter fullscreen mode Exit fullscreen mode

rather than carrying C# naming conventions into the PHP API.

At the same time, the generated WebForms Core commands must remain compatible with the existing WebFormsJS runtime.

This creates an important separation:

The implementation follows PHP conventions.

The generated protocol follows WebForms Core conventions.

That separation is fundamental to a multi-language implementation.

Using WebForms.php

WebForms.php can be used directly by including the PHP class:

<?php

include 'WebForms.php';

use WebFormsCore\WebForms;
use WebFormsCore\Fetch;

$form = new WebForms();

$form->setText("message", "Hello from PHP!");

echo $form->response();
Enter fullscreen mode Exit fullscreen mode

It can also be installed as a Composer package.

After installing the package, the Composer autoloader can be included:

require __DIR__ . '/vendor/autoload.php';
Enter fullscreen mode Exit fullscreen mode

and the WebForms Core classes can be used normally.

A Small PHP Example

A simple example can use WebForms.php to create an interactive game without writing JavaScript business logic.

For example, a small "Flower or Empty" game can be implemented with HTML containing only the interface:

<button value="0" win-with="1">
    🌹 Flower
</button>

<button value="1" win-with="0">
    ✊ Empty
</button>

<p id="computer">
    Computer choice:<span></span>
</p>

<p id="result"></p>
Enter fullscreen mode Exit fullscreen mode

The PHP code then defines the behavior:

<?php

require __DIR__ . '/vendor/autoload.php';

use WebFormsCore\WebForms;
use WebFormsCore\Fetch;
?>

<!DOCTYPE html>
<html>
<head>
    <title>Gol Ya Pooch - WebForms Core</title>
    <script type="module" src="/script/web-forms.js"></script>
</head>

<body>
    <h1>🌹 Gol Ya Pooch ✊</h1>

    <p>Choose one:</p>
    <button value="0" win-with="1" id="flower">
        🌹 Flower
    </button>
    <button value="1" win-with="0" id="empty">
        ✊ Empty
    </button>

    <p id="computer">
        Computer choice:<span></span>
    </p>

    <p id="result"></p>
    <p>
        Games:
        <span id="counter">0</span>
    </p>
    <p>
        Wins:
        <span id="win-counter">0</span>
    </p>
</body>
</html>

<?php

$form = new WebForms();

$form->setCommentEvent("<button>*", "onclick", "play");
$form->setFontSize("<button>*?.<p>*", 40);

$form->startIndex("play");

// Increase game counter
$form->increase("counter", 1);

// Generate and save computer choice
// 0 = Flower, 1 = Empty hand
$form->addSaveValue("random", Fetch::random(0, 2));

// Player wins
$form->isEqualTo(Fetch::getAttribute("$", "win-with"), Fetch::save("random"));
$form->startBracket();
$form->setText("result", "😀 You win!");
$form->increase("win-counter", 1);
$form->endBracket();
$form->else(); // Equal
$form->setText("result", "😢 You lose!");

// Show computer choice
$form->isEqualTo("0", Fetch::save("random"));
$form->setText("computer|<>", "🌹 Flower");
$form->else();
$form->setText("computer|<>", "✊ Empty");

echo $form->exportToHtmlComment();

?>
Enter fullscreen mode Exit fullscreen mode

The example demonstrates an important property of WebForms Core.

The PHP code describes the behavior.

The browser executes the resulting WebForms Core commands through WebFormsJS.

No JavaScript business logic is required for the game.

Game screenshot
Simple Game with WebForms Core

WebForms.php 2.1 and WebFormsJS 2.1

WebForms.php 2.1 is designed for WebFormsJS 2.1.

The two components work together as the server-side command generator and client-side executor.

WebForms Core 2.1 introduced a large number of new capabilities, including nested conditions, Then, Repeat, ForEach, advanced element selection, WPC criteria, State improvements, template rendering, debugging, improved history management, and other runtime improvements.

The PHP implementation exposes the corresponding server-side API for PHP applications.

WebForms Core 2.1 was also extensively tested for compatibility between its WebForms classes and WebFormsJS. The main 2.1 release went through more than three months of compatibility testing and reported a greater than 99% test success rate.

Package Distribution

WebForms.php is distributed as a Composer package.

The package name is:

webforms-core/php
Enter fullscreen mode Exit fullscreen mode

It can be installed with:

composer require webforms-core/php
Enter fullscreen mode Exit fullscreen mode

The package uses Composer autoloading so that the WebForms.php implementation is loaded through:

require __DIR__ . '/vendor/autoload.php';
Enter fullscreen mode Exit fullscreen mode

This makes WebForms.php available through the standard PHP package ecosystem.

Conclusion

WebForms.php 2.1 is not simply a translation of C# code into PHP syntax.

It is a PHP implementation of the WebForms Core 2.1 server-side programming model.

The development process was also an experiment in AI-assisted multi-language development.

DeepSeek performed the initial conversion.

Manual review identified language-specific differences.

Qwen independently evaluated the result and identified semantic compatibility problems that were not obvious from the syntax alone.

The final implementation was then corrected and tested.

The experience demonstrated something important about using AI for software porting:

AI can significantly accelerate a language conversion, but successful porting requires more than generating syntactically valid code.

The difficult part is preserving behavior across languages.

C# and PHP have different type systems, different conventions, different overload mechanisms, and different runtime behavior.

A reliable port therefore needs to preserve the protocol and semantics while allowing the implementation to become native to its destination language.

You can use the PHP version with complete confidence. If there is any problem, it will be fixed very soon by Elanat.

That is the approach used for WebForms.php 2.1.

DeepSeek converted it.
Qwen evaluated it.
Testing validated it.
WebForms.php 2.1 is now released.

Top comments (0)