Skip to content

Instantly share code, notes, and snippets.

@Ocramius
Created December 26, 2015 18:26
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ocramius/02c3a9e6db97ca4a018a to your computer and use it in GitHub Desktop.
Save Ocramius/02c3a9e6db97ca4a018a to your computer and use it in GitHub Desktop.
Form validation from HTML form
<?php
$formHtml = <<<'HTML'
<form action="%s" method="post">
<label for="email">Email:</label>
<input
type="email"
id="email"
name="email"
value=""
aria-describedby="email-description"
data-reuse-submitted-value="true"
data-validator="email-address"
required="required"
/>
<span id="email-description" class="help">Enter a valid email address</span>
<input type="submit"/>
</form>
HTML;
$form = $formFactory->fromHtml($formHtml);
var_dump($form->validate($_POST)); // returns form validion result VO
echo $form->asString();
@Ocramius
Copy link
Author

Someone make this happen.

@Fedik
Copy link

Fedik commented Dec 26, 2015

in theory DOMDocument can help, or?

class FormFactory{

    protected $document;

    funstion __construct(){
        $this->document = new DOMDocument('1.0', 'utf-8');
    }

    function fromHtml($formHtml) {
        $this->document->loadHTML($formHtml);
    }

    function validate($data) {
        $inputs =  $this->document->getElementsByTagName('input');
        foreach($inputs as $input){
            $this->validateInput($input, $data);
        }
       ...
       ...
    }
}

@Ocramius
Copy link
Author

@Fedik yes indeed, it can :-)

@mickaelandrieu
Copy link

@Ocramius this is how I see a real Form library too, and why I'm against the new way of declare Form Types in Symfony :(

@Ocramius
Copy link
Author

@mickaelandrieu while I understand where @webmozart went with that, I fully agree: the form systems are too complex and too magical, and too far from the reality of just a form to be displayed, and data to be filtered through it (moving it out of/into objects is a separate concern IMO)

@Fedik
Copy link

Fedik commented Dec 27, 2015

there is https://github.com/joomla-framework/form not exactly what you dreams about, but close ... on some points :)
it works with "XML forms"

$formXml = <<<MYFORM
<form>
  <field type="email" name="email" label="Email:"
    required="true" rule="email" message="Enter a valid email address"/>
</form>
MYFORM;

$myForm = new Form('myform');
$myForm->load($formXml);
$myForm->validate($_POST);

but there is no asString(), all fields need to render "manually" :/

@Ocramius
Copy link
Author

@Fedik that is kinda useless: what I want to get rid of is a DSL for forms that is NOT an HTML form. The HTML forms specification includes loads of stuff that already covers most use-cases of forms, therefore we should just stop re-implementing it from scratch.

@gmazzap
Copy link

gmazzap commented Dec 28, 2015

@Ocramius nice idea. Probably I would use 3 different validation methods: validateFromGlobals() ($_POST or $_GET depending on form method) validateArray() and validateRequest() for PSR-7 request object.

Also, you probably need to know when form is submitted and when not.

/** @var FormLib\FormtInterface $validation */
$form = $formFactory->fromHtml($formHtml);
/** @var FormLib\ValidationObjectInterface $validation */
$validation = $form->validateFromGlobals();
/** @var string[] $messages */
$messages = $form->isSubmitted() ? $validation->getErrorMessages() : [];
/** @var array $data */
$data = $form->data(); // strips any information in globals that is not provided by form, empty when form not submitted

if ($messages) {
   vprintf(
     '<ul class="form-errors">'.str_repeat('<li>%s</li>', count($messages)).'</ul>',
     array_map('htmlentities', $messages)
   );
} elseif(!$form->isSubmitted()) {
  echo $form; // __toString()
}

if ($data) {
   $success = do_something_with_data($data);
   echo $success ? '<p>Thank You!</p>' : '<p>Something bad happened.</p>';
}

Regarding implementation, using https://github.com/Level-2/Transphporm should be quite simple.

@Ocramius
Copy link
Author

Those are controller concerns imo, not form's.

@geerteltink
Copy link

@Ocramius
Copy link
Author

@xtreamwayz that kinda resembles my thoughts. I forgot to mention that @jstoone already started work on this at jstoone/HTMLFormValidator#1

Opened https://github.com/xtreamwayz/html-form-validator/issues/1 to avoid you folks stumbling on each other by accident (do it on purpose!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment