I have recently begun working on a PHP/JS Form Class that will also include a SQL Form builder (eg. building simple forms from sql and auto inserts/updates).
I have tried several classes (zend_form, clonefish, PHP Form Builder Class, phorms etc) but as yet haven't come across a complete solution that is simple, customizable and complete (both server side and client side validation, covers all simple html elements and lots of dhtml elements: sorting, wysiwyg, mutli file upload, date picker, ajax validation etc)
My question is why do some "classes" implement elements via an array and others via proper OO class calls.
eg.
Clonefish (popular commercial php class):
$config = Array(
'username' => Array(
'type' => 'inputText',
'displayname' => 'Username',
validation => Array(
Array(
'type' => 'string',
'minimum' => 5,
'maximum' => 15,
),
),
));
$clonefish = new clonefish( 'loginform', 'test.php', 'POST' );
$clonefish->addElements( $config, $_POST );
Then others eg. Zend_Form
$form = new Zend_Form;
$username = new Zend_Form_Element_Text('username');
$username->addValidator(new Zend_Validate_Alnum());
$form->addElement($username);
I realise Zend_Form can pass elements in via an array similar to clonefish but why do this?
Is there any benefit? It seems to make things more complicated especially when using a proper IDE like Komodo.
Any thoughts would be appreciated as I dont want to get too far down the track and realize there was great benefit in using arrays to add elements (although this wouldn't be much of a task to add on).
Cheers
My question is why do some "classes" implement elements via an array and others via proper OO class calls.
For convenience. It's less verbose and it feels less like coding and more like configuration and you need less intimate knowledge of the API.
Btw, the reason you have not yet come across a complete solution that is simple, customizable and complete is because it is not simple. Forms, their validation and rendering is complex, especially if you want to have it customizable for any purpose. ZF's form components are a good example of how to properly decouple and separate all concerns to get the ultimate extensible form builder (including client side code through Zend_Dojo or ZendX_Jquery). But they are also a great example of the complexity required for this. Even with the convenient array configuration, it is damn difficult to make them bend to your will, especially if you need to depart from the default configuration and rendering.
Why to use objects? Becouase they are a much more complex types. Consider the following example (I never useed Zend_Form so I don't even know its architecture):
class MySuperAlnumValidator extends Zend_Validate_Alnum {
protected $forbiddenWords = array();
public function addForbiddenWord($word) {
$this->forbiddenWords[] = $word;
}
// Override Zend_Value_Alnum::validate() - I don't know whether such a method even exists
// but you know what's the point
public function validate() {
parent::validate();
if (in_array($this->value, $this->forbiddenWords) {
throw new Exception('Invalid value.');
}
return $this->value;
}
}
// -----------------------
$validator = new MySuperAlnumValidator();
$validator->addForbiddenWord('admin');
$validator->addForbiddenWord('administrator');
$username->addValidator($validator);
This is only a simple example but when you start writing more complex validators/form fields/etc. then objects are, in principle, the only meaningful tool.
Related
I've a set of data (~30 properties, all having their own array of values) that I want to pass around to various classes in PHP and I want to also enforce the data's array structure. Multiple classes will be expecting this structure to be consistent.
Because of these facts I can't really rely on a standard array and so I decided to pass an object around. I looked into ArrayObject and while it allows me to set/get as if the class were an array I didn't see anything about enforcing the structure.
Is there an existing standard class that can handle enforcement of it's array-like structure while still being treated as an array, e.g., basically ArrayObject + enforcement?
An example of the array structure:
$item_type_props = array(
'phone' => array('speed' => 1000, 'self_label' => false, 'support_poe' => true, 'bluetooth' => false),
'pbx' => array('acd_support' => true, 'max_conn' => 300, max_phones => 600),
'adapter' => array('fxo' => 4, 'fxs' => 0, 't1_e1_pri' => 0),
etc...
);
I know each property in the array could be it's own class and enforce it's own fields through the constructor and set/get but then I suddenly have ~30 classes that are nothing but a bunch of attributes and that seems somewhat excessive for just holding data.
Alternatively, if I'm just approaching this from the wrong mindset and missing something really, really obvious then please do point it out. I get the feeling that I am but my brain might be having a vacation.
While you could roll your own, I encourage you to use an existing validation implementation. For example, Symfony\Validator allows you to define nested structures and the requirements on each level:
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
$validator = Validation::createValidator();
$constraint = new Assert\Collection(array(
// the keys correspond to the keys in the input array
'name' => new Assert\Collection(array(
'first_name' => new Assert\Length(array('min' => 101)),
'last_name' => new Assert\Length(array('min' => 1)),
)),
'email' => new Assert\Email(),
'simple' => new Assert\Length(array('min' => 102)),
'gender' => new Assert\Choice(array(3, 4)),
'file' => new Assert\File(),
'password' => new Assert\Length(array('min' => 60)),
));
$violations = $validator->validate($input, $constraint);
This lets you push the details of how to validate down to another (already tested) level, while letting your code focus on why it needs this data. For the Symfony case, you can use an array as the storage mechanism, and use a design that firewalls unvalidated from validated data.
One way we might do this is notationally. Pretend we have implemented a method, perhaps using Symfony's validator, to return a validated array. We can use Hungarian notation to indicate our structure has passed through validation and is "safe":
<?php
$vInput = validate($_GET); // Hungarian notation: any variable beginning with "v" is "validated" and safe to use
function foobar(array $vInput) { ... }
While this is performant, it's not great for maintenance in the long term. So, you might consider an object wrapper that allows you to leverage the type system:
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
class ValidatedArray extends \ArrayObject {
public function construct($input = [], $flags = 0, $iterator_class = 'ArrayIterator') {
$violations = Validation::createValidator()->validate($array, $this->constraints());
// throw exception if any violations
parent::__construct($input, $flags, $iterator_class);
}
public function __offsetSet($index, $value) {
$constraints = $this->constraints()[$index]; // specific constraints to this index
$violations = Validation::createValidator()->validate($array, $constraints);
// throw exception on violations
parent::__offsetSet($index, $value);
}
public function constraints() {
return new Assert\Collection(...);
}
}
$input = new ValidatedArray($_REQUEST); // first time validation
$input['foo'] = 'bar'; // also subject to validation
You might want to make this implementation an abstract base class, with concrete descendants implementing the constraints method to provide the specific limitations on the array object itself. This provides a flexible way to get dedicated Data Transfer Objects.
Generally speaking I would argue that - unless you are passing data to another context, e.g. javascript - a PHP application should be nicely organized in PHP classes. This is simply the easiest way to enforce the structure. Your are right, this might result in quite straightforward DTO's with a bunch of getters and setters, but it will beat checking array structures for sure. In your case there also appears to be a relationship in the array, otherwise it would not make sense combining them into an array at all.
Using PHP7 you can clearly define the method signature and enforce the types, e.g.
public function setSomething(string $myValue)
{
$this->something = $myValue;
}
Same with return types:
public function myActionMethod(array $options): ActionRespsonse
{
// Do something
}
If you have more complex data types, I would recommend using Value Objects. These are nothing more but simple PHP classes that represent a more complex value. For example, a phone number:
public function setPhoneNumber(PhoneNumber $phoneNumber)
{
$this->phoneNumber = $phoneNumber;
}
Here the PhoneNumber is a Value Object which effectively is a tiny class by itself which enforces its usage:
class PhoneNumber {
private $phoneNumber;
public __construct(string $phoneNumber) {
if (strlen($phoneNumber) != 10) {
throw new \Exception('Not a valid phone number');
}
$this->phoneNumber = $phoneNumber;
}
}
This is also where the validation can tie into the answer from #bishop as you can use an existing Validator to help you out. You can find an example of a Value Object of a Phone Number here (just googled it): Example Phone Number Value Object
I do have the feeling that you might be converting your PHP data to an array for another reason? Like interacting with a database, or passing it on to a different context, such as Javascript?
In that case, once you have your DTO's and VO's neatly defined you can then consider serializing them e.g. to/from JSON. You can use Symfony libraries for that, as described here: Symfony Serializer
If you really want arrays you can also consider hydrating them to/from entities, using the library from Marco Pivetta (ocramius) who is pretty much the authority on hydration an approach extensively used in Doctrine: Ocramius Hydrator
Plenty of options, eh!?
To be honest, though, IMHO typically there would need to be a pretty good argument to pass these complex arrays around as arrays offer very little in supporting functionality. In addition, your code will very likely and very quickly become difficult to read and maintain, as at every point where there would be some kind of modification of the array, or usage of its data elements, you would need to implement all kinds of checks or run a validation as described by #bishop. I would not allow something like that to exist in our applications code bases...
So, concluding: If you have a tightly defined set of PHP Objects with well established constructor, properties, getters, setters, constructor, relationships, action methods and besides that some kind of serializing mechanism, you're in good shape. Also other developers will be 'forced' to work with the objects and provided interface (methods and VO's) thus guaranteeing a degree of maintainability and quality.
By the way, you might consider reasing Martin Fowler's thoughts about these things: Martin Fowler: DTO Martin Fowler: VO Martin Fowler: DTO2
Ok so i've got a big problem with CodeIgniter flexibility. I've many personal rules (like 20) targeting an input in a form within a huge project.
Everything work while I use the classic "callback_" system by CodeIgniter. I just put the methods in the same class than the form check and it checks it correctly.
My problem is :
1) I'd like to use all these rules in another form_validation in another controller without copy/paste the code ; we all know it's dirty/evil.
2) Ideally, i'd appreciate to put these rules in a big library, because it takes something like 800 lines and this is not a good idea to let it be in my controller ; as I said this project is quite huge.
It's 6 hours i'm looking for a solution and there's absolutely nothing clean :
I already have a MY_Form_Validation to put some general rules but i don't like the idea to mix my specific rules in a global class which will call it everytime vainly. Plus these rules contain many libraries, models, native CI core methods such as $this->input->post() which generate errors when I put everything in this MY_Form_Validation. Not the good solution :(
I created a MY_Controller including a method named 'imports' which re-generate selected libraries methods within the controller (in PHP4 it was kind of the 'aggregate_methods' function if people are curious) ; the system works perfectly but CodeIgniter doesn't understand it. The methods can be called within the controller but it seems the framework check the $CI content to call the rules (Form_validation.php line 590 in '/system/') so it doesn't work at the end ; it's also hard to modify this core part, I prefered not touching it and gave up.
$this->load->library('volt/lbl_validation');
$this->imports('Lbl_validation');
// Then you can call any $this->lbl_validation->method() with $this->method() in the controller
I tried to hack CI creating a customized form_validation within my library ('lbl_validation') ; the system was a bit messy but worked. The problem is when i came back to the CI form_validation system to show error messages, it was a true spaghetti-code which wasn't working that well. Not the good solution either.
I also tried some other shitty solutions but i prefer not confess it.
Now i'm here in front of my computer asking myself why bad things happened to good people, why this is so hard to separate set_rules from the called methods in CodeIgniter, why they didn't plan ahead people could've needed to call libraries methods as rules. I don't know what to do and i'm hesitating to put a dumb require() somewhere and make it all dirty and messy like my desk right now.
Maybe, there's someone with a good dans clean solution. All my hope are turned to the StackOverFlow community ; someone ? A crazy CI geek ?
Thank you ;)
The only good, DRY way to handle validation is to put validation rules at the last resort before saving to the the database, in other words in the models. By doing this, the same rules can be used in any controller or library without being redefined.
The following idea is taken from Jamie Rumbelows excellent Codeigniter handbook:
Simply create an array in your model:
$validate = array(
array( 'field' => 'username', 'label' => 'Username', 'rules' => 'required,trim' ),
array( 'field' => 'password', 'label' => 'Password', 'rules' => 'required|min_length[8]' )
);
Then implement a method that you can use to validate your data prior to save()
function validate($data) {
if (!empty($this->validate)) {
foreach ($data as $key => $value) {
$_POST[$key] = $value;
}
$this->load->library('form_validation');
$this->form_validation->set_rules($this->validate);
return $this->form_validation->run();
}
else
{
return TRUE;
}
}
Now, in your controllers you can use:
if ($this->user->validate($user))
save...
I have site which is managed using CMS entirely developed on zend. Now I have to Implement a search feature too. I'vent done anything related to search in zend. Some suggestions that I received is to implement a spider. The site will have plenty of links(and it will keep on adding). I'm totally confused and I don't know where to start from. Will zend_search_lucene do the trick?
You probably aren't going to find something completely turnkey for this. If your content is all public, and you are fine with just using a crawler, the easiest thing to implement could be Google Site Search.
http://www.google.com/enterprise/search/products_gss.html
If you need to get different functionality out of the search that this wouldn't offer, you'll likely be stuck doing some code. The Zend Lucene link that Alvar posted is good. One of the ugly things about Zend_Lucene, if I am not mistaken, is that it's relying on the text based lucene indexes without any Java. It's just slower and more cumbersome to manage.
A more robust Lucene based approach is Solr. It's Java based, and runs on it's own service with an API. It scales well, and there's a PHP Pecl out now that will help you communicate with it.
See http://php.net/manual/en/book.solr.php
Another option is Sphinx. This search engine bolts directly to your database, so indexing might be a little more intuitive.
http://sphinxsearch.com/
Good luck to you!
Lucene is strange, i never got it to work properly and developed my own search logic, but maybe this helps:
http://devzone.zend.com/397/roll-your-own-search-engine-with-zend_search_lucene/
Because you are using a home grown product you'll likely be better served by keeping things as simple as possible, at least in the beginning. Also because you're product is home grown you should have a pretty good handle on the data structure.
Building a simple query based search may be something appropriate for starters.
I started with a simple search form:
<?php
class Application_Form_Search extends Zend_Form
{
public function init() {
$this->setMethod('POST');
$this->setDecorators(array(
array('ViewScript', array(
'viewScript' => '_searchForm.phtml'
))
));
// create new element
$query = $this->createElement('text', 'query');
// element options
$query->setLabel('Search Keywords');
$query->setAttribs(array('placeholder' => 'Title',
'size' => 27,
));
// add the element to the form
$this->addElement($query);
$submit = $this->createElement('submit', 'search');
$submit->setLabel('Search Site');
$submit->setDecorators(array('ViewHelper'));
$this->addElement($submit);
}
}
then I built a simple action helper to display and route the form:
<?php
class Library_Controller_Action_Helper_Search extends Zend_Controller_Action_Helper_Abstract
{
public function direct($action, $label = null, $placeHolder = null)
{
$form = new Application_Form_Search();
$form->setAction($action);
$form->search->setLabel($label);
$form->query->setAttribs(array('placeholder' => $placeHolder,
'size' => 27,
));
return $form;
}
}
then I added a placeholder for the search form in my layout.phtml
<?php echo $this->layout()->search ?>
then in the controllers that need to use the search function I add the helper to predispatch():
public function preDispatch()
{
//assign search action helper to view placeholder
$this->_helper->layout()->search = $this->_helper->search(
'url_for_action', 'Submit button label', 'placeholder text'
);
}
then I use a simple mapper method to perform the appropriate query and I usually return a paginator adapter:
public function fetchPagedMoviesByTitle($title)
{
$select = $this->getGateway()->select();
$select->where(new Zend_Db_Expr("title LIKE '%$title%'"));
$select->order('title', 'ASC');
//create a new instance of the paginator adapter and return it
$adapter = new Video_Model_Paginator_Video($select);
return $adapter;
}
This is simple way to implement a search function and is adaptable to most types of queries. I find that a switch statment and a couple of simple database queries and almost any information I need is available.
Good Luck.
I have only recently started web programming and I am pretty much amazed that although I am using a validation library, I still get 20-30 lines of code for validation alone, not counting error messages and callback functions. I am using the Kohana MVC framework and I was wondering if there was any way I can shorten my validation codes. I tried to think of the following
putting validation codes in my model (which is quite had for a noob like me).
creating a really small library to validate entries(something that hooks to the validation class, thus allowing me to call the library for repetitive procedures like user registration, editing and stuff)
Or are there any better and more efficient ways?
I would highly recommend working on including the validation in the model. Once you are able to do one, any others you create will be much easier. Plus if you have multiple controllers trying to save that data, you will not need to recode the validation. The Kohana docs contain some examples for integrating the validation library and ORM, you should start there.
I use Zend_Validate with Zend_Forms for validation in which the validation code is in the forms init method. All I have to do is pass an array of validators for each element and than run ..
$form->isValid($data);
...outside of the form to validate the data.
The validation array is easily more than 30 lines because I seperate each array entry with a newline. But i guess you will have that if you defining fine grained validation rules for each element right.
And its really easy to define new Validators in Zend.
edit: i discovered a framework that extends the Zend Framework which allows domain objects to contain its own validation. Its called Xyster framework but I could not get it to work on the first try so I haven't tried after that.
Here's my strategy for dealing with validation code. I suppose by 'validation library', you mean those which just make sure an email is an email, telephone numbers are numerical, and are not business rules in nature.
The idea is to have each business rule code as a functor - if it is PHP, you can get by just using a string to define the function; for other languages, you may have to use the strategy pattern. Define an interface for the functor (not necessary for PHP) and dump it into an array.
Run through the array which will return success, error and an error-code to a buffer. At the end, examine the error buffer and determine which validation has failed. Use it to customise the view.
Here's an example
$checkUniqueUserName = new CheckUniqueUserName();
$checkEmailNotUsed = new EmailNotUsed();
$validator = array();
$validator[$checkUniqueUserName->name()] = $checkUniqueUserName;
$validator[$checkEmailNotUsed->name()] = $checkEmailNotUsed;
$results = array();
foreach ($validator as $v)
{
$result[$v->getValidatorName()] = $v->execute($userInfo);
}
class CheckUniqueUserName()
{
public function execute($userInfo)
{
// SQL blah blah blah
if ($bNameUnique)
return array ('success' => 1)
else
return array ('success' => 0, 'error' => "$name is in used", 'error_code' => 'duplicate_name);
}
}
At the end, you will have a results array, each filled with a validation process, and you know which has failed, and which has not. This can then be passed to the client-side for further processing, like highlighting the failed fields. The error_code an be used to look up the proper error message and formatting applied to it.
I am not really sure about what you mean by call-backs though.
How would I go about creating a real world form creation class that I can use to display a new form with fields of different types, as how many fields I want, I can use drop downs and I can do all of this by using OOP?
To be honest I wouldn't roll my own, considering there are a few mature form packages out there for PHP.
I use PEAR's HTML_QuickForm package (http://pear.php.net/manual/en/package.html.html-quickform.php) for PHP4 sites.
For PHP5, I'd have a look into Zend_Form (http://framework.zend.com/manual/en/zend.form.html).
For my quickform code, I use a helper class that lets me define forms using a config array. For example:
echo QuickFormHelper::renderFromConfig(array(
'name' => 'area_edit',
'elements' => array(
'area_id' => array('type' => 'hidden'),
'active' => array('type' => 'toggle'),
'site_name' => array('type' => 'text'),
'base_url' => array('type' => 'text'),
'email' => array('type' => 'text'),
'email_admin' => array('type' => 'text'),
'email_financial' => array('type' => 'text'),
'cron_enabled' => array('type' => 'toggle'),
'address' => array('type' => 'address'),
),
'groups' => array(
'Basic Details' => array('site_name', 'base_url'),
'Address Details' => array('address'),
'Misc Details' => array(), // SM: Display the rest with this heading.
),
'defaults' => $site,
'callback_on_success' => array(
'object' => $module,
'function' => 'saveSite',
),
));
Note that the above element types 'address' and 'toggle' are in fact multiple form fields (basically, meta-types). This is what I love about this helper class - I can define a standard group of fields with their rules (such as address, credit_card, etc) and they can be used on lots of pages in a consistent fashion.
You definitely can. Consider a Form class which stores information about the form itself: the method, action, enctype attributes. Also throw in stuff like an optional heading and/or description text at the top. Of course you will also need an array of input elements. These could probably be put into their own class (though subclassing them for InputText, InputCheckbox, InputRadio maybe be a bit over the top). Here's a vague skeleton design:
class Form {
var $attributes, // array, with keys ['method' => 'post', 'action' => 'mypage.php'...]
$heading,
$description,
$inputs // array of FormInput elements
;
function render() {
$output = "<form " . /* insert attributes here */ ">"
. "<h1>" . $this->heading . "</h1>"
. "<p>" . $this->description . "</p>"
;
// wrap your inputs in whatever output style you prefer:
// ordered list, table, etc.
foreach ($this->inputs as $input) {
$output .= $input->render();
}
$output .= "</form>";
return $output;
}
}
The FormInput class would just need to store the basics, such as type, name, value, label. If you wanted to get tricky then you could apply validation rules which would then be converted to Javascript when rendering.
I will go against other advice here and suggest that you build your own library to generate forms. If you fail, you will still learn a lot in the process.
The design process is most important here. You start from the top and ask yourself what goes on a form. At an abstract level, a form is full of elements. Some are visible, some are not, some can be entered by the user but others cannot, some elements can trigger other elements... and the list goes on...
Eventually you end up with elements that are "decorative" (Text, Headings, Separators, Fieldsets, Links, Images), elements that are interactive (Inputs, Dropdowns, Checkboxes, Radio buttons, Submit Buttons) and finally elements that are neither decorative nor interactive (Hidden Inputs, Anchors and elements that act as containers to group other elements.)
Once you have the different categories organised you start looking into features that all elements have and you can put that into the base element class. Then you go up the chain making your classes doing more and more, inheriting from other simpler element classes. In my library, the base element class is called form_element and each form_element has a unique name that no other element within the same form can have. A form_element also has a set of attributes. It has a function that all elements have called render(). In the base class render() does nothing (so a base element is always invisible) but in derived classes it starts producing HTML. By the way, I never make any of my classes create HTML. Instead I have a static class called html which writes HTML for all the classes that needs its services.
Very early in the chain of form elements, you should have one, a container that groups others. It should have an add() function and its render() function should consist of calling the render() function of all its sub-elements. the form class will be derived from this container class.
Spend plenty of time on the design. Pay attention to compatibility with the rest of your library.
If you want the data from the form to come from a database and be saved to one, you will need to add this functionality and have a form element class linked to a table and column. Here too, I have a separate DB class that can retrieve/save the data. I have a query class that creates queries. Form elements should have nothing to do with creating HTML, creating queries or accessing a database. My static class DB and my query class take care of the dirty work. The form class should only be involved with form stuff. The form class collects into an array all the tables and columns for the fields that need to be saved and pas it to the query class which creates the query which is then passed to the DB class which executes it.
Once you are properly setup, what appears to be horrendously complicated suddenly becomes very easy with properly designed classes.
Because you have a class that can write HTML, your form class needs to just html::init() and follow it with render() and the entire HTML code for the form is available within the html buffer. html::output() flushes everything out.
Validation is also handled externally with a static validation class. Form elements that can be validated hold validation instructions within an array in a format that can be passed directly to the validation class. Each element that needs to be validated is bound to an error element which displays the error if the element does not validate or remains invisible if all goes well.
This is to show you that when you design a form environment (or anything else) you really need to consider absolutely everything before you get started. The work that you put into it may not immediately translate into code that can power your application but it will sure make you a much better developer, thus making your future projects much easier to handle.
The form class creates a form, the html class creates the HTML, the query class makes queries and the DB class handles the database. If your classes start doing work that should be done by separate classes, you have a design problem.
Here is a code sample to show how my form library works:
$fm = new form('myform');
$fm->binding(FORM_DATABASE);
$fm->state(FORM_RETRIEVE);
$fm->set_recno(1);
$fm->add(new form_heading("My form"));
$fm->add($el=new form_input("name",40));
$el->bind_data('mytable','mycolumn');
$el->set_attribute('size', 25);
$el->set_default('Name');
$fm->add($el=new form_submit("submit_btn","Submit"));
if($fm->manage())
{
redirect or do something else here. The interaction with the form is done. The initial state for the form was FORM_RETRIEVE. If it had been FORM_NEW it would have displayed default values instead of the retrieved record and saved the form as a new record in the table.
}
Note that the manage() function of the form takes care of absolutely everything, retrieving data from the database, rendering the form into the view, validating data and saving it back to the database.
One of the advantages of creating forms programmatically (as above) is the option to write your own form-based code generator to create the code to make your forms.
I hope this can help you or someone else.
Just for reference, Object Oriented Forms by Khurram Khan is an excellent OO forms implementation for PHP.
Here is a sample of what the code looks like:
$form = new Form("Register", "form.php");
$personal = new Block("Personal Information");
$name = new Text("name", "Your name");
$name->setDescription("this is my description");
$name->addValidator(new MaxLengthValidator("The name you have entered is too long", 30));
...
Another more popular implementation is PHPlib. However, I find this to be a bit clunky; it seems like it's just some standard functional programming wrapped in a class.
Another option would be writing an abstraction for the built in DOM library. This will allow you to manually create any kind of form and form element using OO notation, with the added benefit that you will be returned an OO DOM instance that can be used elsewhere in your program.
You definitely should use OO PHP to do forms, and all the rest of your HTML output. I could not find any PHP library (many of the links in these answers are dead) to do what I wanted, so I wrote PHPFUI. It is not a generic HMTL output library, but outputs pages for the Foundation CSS Framework. You could easily use the same technique to output a more vanilla page, or Bootstrap or what ever. I did not want to write a generic HTML OO PHP library, as I wanted something lean and mean for performance reasons. Also I don't like to over engineer stuff, so it is hard coded to Foundation. But the same principles would apply to any PHP library that would want to output clean HTML with no validation issues, which you often find in hand written HTML.