ado| programming
The 2nd Chapter uses Prado programming
Now let's take a deeper look at the Prado framework. In this chapter we will introduce the basic concepts of some frameworks and how to use existing Prado components to develop a Prado application.
2.1 Component
According to Clemens Szyperski, the ' software component is a modular unit with a specific interface that can exist independently and participate in the formation of other builds. ''
In Prado, a component is an instance of Tcomponent or its subclasses. The Prado framework already includes the tcomponent
class, which mainly implements the component's properties and event mechanisms.
- A property can be considered a public variable that describes an attribute of a component, such as background color, font size, and so on. Attributes are of type, such as string, integer , and so on. Properties can be read-only or writable.
- Events enable the proxy function to respond to some of the activities in the component, such as mouse clicks, input text changes, and so on.
A component inherits the properties and methods of all its parent-class components, because the component itself is actually a class.
A complete component class definition consists of two files:
- A class file that defines the logic of the component class. This file is mainly PHP code. The file name must be the same as the class name, and the . php file suffix.
- A specification file that defines the properties and methods of a component class. This file is in XML format. If this component class does not define new properties and events other than the parent class, then the file can be omitted. By default, the file and component's class files are in a directory, and the names are the same, except for their filename suffixes (the suffix of the class file is. php , the specification file is . Spec ). It is worth noting that Prado also allows you to name specifications and template files with different filenames, but the class file name must still follow the rules of the class with the suffix . php . At this point you need to specify the file name of the specification file's containing path in the class's constant specification_file , using an absolute or relative path (relative to the location of the class file).
Note: PRADO are case-sensitive, component types, attribute names, event names, file names, and so on, all of which are case-sensitive.
2.1.1 Control
A control is a Prado component that defines a user interface. Each control has a parent control and some child controls (note that the concept of parent-child relationships and child-oriented subclasses is completely different.) A control that is the parent of another control simply shows that the former has the latter, and that the owning relationship can be understood to include a subdirectory in a directory, not the latter being a subclass of the former, or the concept inherited from the former. A page is the highest level of control, and it does not have a parent control (you can also think of application as its parent control). A Prado application is a collection of pages, each representing a hierarchical tree-structured set of controls that are linked by a parent-child relationship.
This parent-child relationship can be established through a template file. The format of the template file is similar to that of HTML, except that some special tags are added to the HTML to set the control. If a control's label is included by another control's label, the former is considered a child control of the latter. Static text is also considered a child control.
Control can have a template file to describe its interface content. By default, template files and class files are in the same directory, and the file name is the same, and the template file has a suffix of . TPL . As with the specification file, if you need to place the template file in different places or use the file name of the turtle, you can specify the location of the template file by setting the value of the class constant template_file .
Each control has an ID, which can uniquely identify the control itself at the same level of control. The ID path is a sequence of all control IDs from the current control to the target control in the control's tree structure, which can be used to access a control. For example, in
In homepage , there is a Menu control that has a child control Button . For control homepage , the Button control can be accessed through an ID(Menu,button) path. If you write with PHP code, you are $this->menu->button .
2.1.2 instantiating a component
There are two ways to instantiate a component. One way to do this is to define it in the template file of a control, and when the control is created, the framework automatically instantiates the component. Another approach is to manually instantiate in the PHP code. Let's take a look at the previous static creation method and look at the dynamic creation method later.
To create a component statically
Typically, only controls are created statically in the template file.
A control is declared in the template file component label, and its syntax is as follows:
......
<com:componenttype id= "..." Propertyname= "..." Eventname= "..." >
..... body contents ....
</com:ComponentType>
......
Here ComponentType, PropertyName, and EventName should be replaced by real component class names, property names, and event names. The ID attribute is optional. If the ID attribute is defined, then the value of the ID must be unique within the control of the peer. If not defined, the framework automatically assigns a unique ID to the control. Of course, this requires that the component's tags are properly nested, and that each open component label should be paired with a closed component tag, which is the same as the rules of XML. (Translator: If you don't know anything about XML, it's a good idea to look at some basic XML concepts, and you just need to know how to write an XML file correctly.) )
Note: The ID of the control must be a letter, followed by a string containing only letters, numbers, and underscores.
The initial value string for the property in the template file is automatically converted to the correct property type. There are currently six types of properties: string, integer, float, boolean, array
Face= "Courier New" > and object. The previous three types of string formats are very simple. Boolean type only allows two strings to be used: true
Face= "Courier New" > and false. The array type accepts the same string as the (value1,value2,key3=>value3,...) format, which is the same as the initialization of the PHP array. The object type is more complex, depending on how the attribute is defined. Some properties can allow strings to be used and convert them to objects, but some properties are not.
When a component is created (instantiated), the attributes of the component defined by the specification file and the corresponding event handling method are immediately effective.
Dynamically creating components
PRADO
Allows developers to instantiate components in their own PHP code. A component can be instantiated by calling a static class method Application::createcomponent ($type) , and the parameter of the method $type indicates the name of the component to be created. Components can also be instantiated using the new operator. The difference between the two methods is that the former uses a caching mechanism that is much faster when the same component is created the next time, and the latter does not use the caching mechanism, each time performing the instantiation step completely. Usually you should use tapplication::createcomponent ($type) to instantiate (if you want to know more, refer to the comments below).
If the newly created component is a control, you can use the control as a child control of another control by calling it. Note that if you need to specify the ID of this control, you should specify the ID before adding it as a child of another control, otherwise the framework will automatically assign an ID to it, and the ID cannot be changed.
Note: If you use or request a resource handle in a constructor, you can only instantiate it using the new operator. Because Prado uses a caching mechanism to instantiate the component, if the resource handle is used in the constructor, the resource handle portion of the data read from the cache next time it is instantiated will still correspond to the original memory address, which can easily cause the system to crash. So if you want to design a component of your own, and try not to use and request a resource handle in the constructor as much as possible, you should organize the code in a different way and call it in a OnInit event or other event on the page. In general, constructors simply need to implement simple variable initialization. In the core code of the Prado, none of the component's constructors are using the resource handle. When you develop your own components, you can refer to their source code.
2.1.3 Accessing Component Properties
PHP 5 uses a good way to access the properties of a component. You can use the properties of a component as a member variable of a component. For example, to set the Text property of the TButton control, you can use the code $button->text= "xxx" , where $button represents an instance of the control. For a control, you can also use its ID path to access the property. Assuming that the Homepage page now has a child control MenuBar , and theMenuBar Control has a child control HyperLink , the code that can be used in the page environment is $ This->menubar->hyperlink->navigateurl to read the NavigateUrl property of the HyperLink control.
Note that because of a bug in PHP5.0, if you need to set the value of a property, you must first obtain the control by its control's ID path, and then set the value of the property. In the example above, you need to set the NavigateUrl property with the following two lines of code.
$link = $this->menubar->hyperlink;
$link->navigateurl= "...";
If you use $this->menubar->hyperlink->navigateurl to set property values directly, an error occurs. But you can also set the value of the property by following this code, so you can avoid that error.
$this->menubar->hyperlink->setnavigateurl ("...");
2.1.4 Using Events
Event response functions are usually assigned to the corresponding event in the specification file or template file, specifying that the event response function is similar to the initial value of the specified property. Note that the event response function specified in the specification file or template file must be defined in the component corresponding to the specification file or template file, and its syntax is as follows:
function HandlerName ($sender, $param)
{
...
}
Here $sender Point to the control that triggers the event, $param is the argument to the event, and its content depends on the type of event.
You can also use the Tcomponent::addeventhandler () method to dynamically specify an event response method when you are programming.
You can specify multiple response methods for an event. When this event is triggered, all specified response methods are invoked automatically. Therefore, Prado implementation is a multicast event triggering mechanism.
2.1.5 data Binding (Binding)
Only controls can be data-bound.
You can bind an expression to the property of the control, and when the DataBind () method of the control is invoked, the value of this property is automatically set to the value of the expression. Data binding is useful when developing data components, many of which are derived from data provided by the source. You can set the data binding in the specification or template file of the component, or you can set it in the code.
To set data binding in a template, simply assign a valid PHP expression string to the value of the attribute and prefix it with a # . For example, use the following code in the page template file:
<com:tlabel text= "# $this->page->id"/>
This code binds an expression to the Text property of the Tlabel component $this->page->id . The function of this expression is to get the ID of the page on which the current control resides. Note that the $this in this expression refers to the Tlabel control itself, because the context in which the $this resides is in Tlabel .
To set data binding in your code, you can invoke the BindProperty () method of the component, which does not need to precede the character # .
Note that an expression that is bound to a property evaluates the value of the expression only when DataBind () is invoked and assigns it to the property. You can refer to the documentation for the dataBind () details.
In addition, if you need to assign an initial value to a property in the template file, rather than data binding, if the value starts with a # , you should repeat it once, just like propertyname= "# # ..." the same.
2.1.6 PRADO Component Class tree
The currently published PRADO includes the component tree shown below, and the properties, events, and classes of these components can be found in the PRADO document.
Tcomponent
Tadodb
Tcontrol
Texpression
Tform
Tliteral
Tpage
Tplaceholder
Trepeater
Trepeateritem
Tstatements
Twebcontrol
TButton
Tcheckbox
Tradiobutton
Tdropdownlist
Thyperlink
Timage
Timagebutton
Tlabel
Tlinkbutton
Tlistbox
Tpanel
Ttextbox
Tdatepicker
Thtmlarea
Tvalidationsummary
Tvalidator
Tcomparevalidator
Tcustomvalidator
Trangevalidator
Tregularexpressionvalidator
Temailaddressvalidator
Trequiredfieldvalidator
2.2 page
A page is an instance of a tpage or its subclass. It is the highest level of component, that is, there is no parent component and it is not included in a container. The application of Prado is made up of some pages.
2.2.1 the life cycle of a page
Understanding the life cycle of a page is very important to mastering Prado programming.
First of all, we want to introduce the concept of postback . We refer to the submission of a form as postbackif the form's data is submitted to the page that contains the form. Postback can be considered an event that is triggered by the user at the client. Prado will tell which server-side component to give the postback event to respond to. If this component is found, for example, a TButton
, we refer to this TButton component as the sender of the event (sender).
The page passes through several states when it is requested to call. When a page is invoked because it has a postback, the page experiences the following lifecycle:
- Page creation: page and all of its subcomponents are created recursively. The framework initializes the properties of the component based on the configuration of each component's specification file and template file. You can overload the page with a constructor to do some other initialization work, such as assigning some default values to some attributes. It should be noted, however, that in this step it is not possible to access other components, because the relationship between components is not yet established.
- OnInit event: The OnInit event is broadcast to the entire page's component tree (that is, all components will be triggered OnInit events). You can overload the OnInit () method of the page or specify a processing method for the onInit event to do some initialization work, such as establishing a database connection, and so on. This is when the relationship between the component and the component has been established.
- Import display Status (Viewstate): Imports the previous display status into the page. The page itself saves the state that was last displayed to the user. There is a more detailed explanation for the display status in the next chapter.
- Import submitted data: the properties of some components in the page are updated based on the data submitted by the user. For example, the text property of theTtextbox component will be updated by the user entered in the Text entry box for this component.
- OnLoad event: At this stage, the page is set to the state that the user sees before submitting. OnLoad
Events are also broadcast to the component tree of the entire page. You can also overload the onload () method or specify a handler function for the onload event.
- Import submitted data: Some components created in the OnLoad step have the opportunity to import the submitted data at this time.
- Generate a commit data change event. If the data for a component is changed by the user, an event is created to indicate the change. For example, the user changes the value of a ttextbox component's text input box, and the ttextbox component triggers a ontextchanged event. Developers can specify the processing method for this event.
- Input validation: If the submitter of the event needs to validate, then the validation component of the page registration will be the corresponding data.
- Postback event: The postback event is triggered by the sender of the event. For example, when a user clicks a button to cause a postback, the button's corresponding TButton component triggers an event OnClick. You can specify the handler function of this event to respond to this event.
- OnPreRender event: In this step, the page has completed the import of the submitted data and the handling of the postback event. The OnPreRender event is broadcast to the component tree of the entire page. Before the page is drawn, you can overload the onPreRender () function or assign an event handler function to the onPreRender event.
- The display state of the entire page's component tree is saved in a fixed storage space (such as a hidden field of a form, session, or database).
- The page is displayed in a recursive way, and the components in the page display themselves (meaning that each component is responsible for displaying itself). Typically, the component displays itself in the location of the template that corresponds to it. You can also overload the Tcomponent render () method to control the display of the component itself.
- OnUnload Event: The page and all of its subcomponents are freed from memory. Similarly, this event is also broadcast to the entire page's component tree. You can do some cleanup work by overloading the onUnload () function or by assigning a handler function to the onUnload event, such as disconnecting the database and so on.
The life cycle is simpler when the page is first requested. In particular, import the display status, import the submitted data, generate the submission data change events, input validation and postback events are not the states.
2.3 Application
Every PRADO Web application has a single instance. It is primarily responsible for encoding and decoding user requests, Server page requests, and maintaining application-level parameters.
2.3.1 the configuration of the application
Each Prado application should have an XML-formatted configuration file. In the example "Hello World", this file is named Application.spec .
The format of the application configuration file is as follows:
<?xml version= "1.0" encoding= "UTF-8"?>
<application default-page= "..." cache-path= "..."
Session-class= "..." user-class= "..." >
<alias name= "..." path= "..."/>
<alias name= "..." path= "..."/>
<using namespace= "..."/>
<using namespace= "..."/>
<secured page= "..." role= "..."/>
<secured page= "..." role= "..."/>
<parameter name= "..." >...</parameter>
<parameter name= "..." >...</parameter>
<parameter file= "..."/>
</application>
The alias element defines the name of the file path, which can be an absolute or a relative path.
The using element defines the namespace to be added to the PHP search path include_path variable. The namespace is "." Number of the connection. The first paragraph is the alias of the path, followed by the subdirectory. For example, System.Web.UI represents the web/ui/ subdirectory in the directory where the framework resides. The alias for the directory of the framework has been defined as System . When programming, you can also call the using () function to add a namespace.
The secured tag is known as whether the page needs to be validated/authorized, and the page property is named either by the name of the sheet or by the matching expression of the page name. If a page is marked Yes, then the page needs to be validated by the user. In addition , if the role attribute is not empty, the user is required to belong to the specified roles.
The parameter element defines a user parameter. You can import a parameter file by setting the file property of the parameter element. The format of the parameter file is as follows:
<?xml version= "1.0" encoding= "UTF-8"?>
<parameters>
<parameter name= "..." >...</parameter>
<parameter name= "..." >...</parameter>
</parameters>
The default-page property and the Cache-path property are well-known for the default page and cache path. If the application needs to use session, the Session-class property also needs to be set. If the application requires validation/authorization support for the framework, you should also specify the User-class attribute.
2.3.2 Page Service
PRADO uses the Get Variable page to indicate the page you want to request. For example, the following URL:
/examples/phonebook.php?page=addentrypage
This code will request a addentrypage page. If you do not specify a page variable, the default page in the application configuration is invoked.
You can also use the Tapplication::constructurl () method to request a page.
2.3.3 data encoding and decoding
By default tapplication will HTML-encode all post and get data. ', ' <, >, & will be converted to ',"e;,<,> and &. The reason for encoding is to allow these characters to be RP to the database and to display them back to the user correctly. If necessary, you can call the pradodecodedata () function to decode it. You can also overload the tapplication::beginrequest () function without encoding.
2.4 Defining new components
There are two ways to define a new component class: Inheritance and composition.
Inheritance is an object-oriented design concept. A derived class defines some of the contents of its parent class, and it can provide some additional functionality. In the Prado framework, the properties and events of a component can be inherited. Derived classes can also provide more properties and events. All component classes should inherit from Tcomponent or its derived classes.
Properties and events for all parent components are inherited by the derived component class.
A combination is a component-based framework. In Prado, the control is used primarily for controls. A new control class can be defined as a combination of several other controls. The new class is responsible for coordinating communication between these controls and communicating with the outside world on their behalf. For example, you can define a Labeledtextbox control class (inherited Tcontrol ), which consists of a Tlabel control and a Tlabel
Control is composed of. The new class is responsible for configuring the properties and methods of these two constituent controls.
General conventions (not enforced), the first letter of the ID and attribute of the control should be capitalized, such as homepage, NavigateUrl,
Logopict The event starts with on, such as OnClick . The name of the ID and the attribute, like the variable naming, must begin with a letter and include only alphanumeric and underlined strings.
To define a new component, you usually need to write a component class file, a specification file, and a template file. Sometimes two files are not available at the back.
2.4.1 Defining Attributes
The attributes of the component are defined in the specification file of the component class, and the specification file has the following syntax:
<?xml version= "1.0" encoding= "UTF-8"?>
<component>
......
<property name= "<property name>"
get= "<getter method>"
set= "<setter method>"
Type= "<property type>"
default= "<default value>"/>
......
</component>
Here,name is used to uniquely identify the attribute; Get defines a class method to read the property,set defines a class method to write the property, and type defines the property ( String, integer, float, boolean, array , and object), default identifies the defaults for the property. Where the name attribute is required. The syntax for the Getter method is as follows:
function Gettermethodname ()
{
....
Return $value.
}
If an attribute is not readable, do not set the get property. The syntax for setter methods is as follows:
function Settermethodname ($value)
{
Set some variable with $value
}
If an attribute is not writable, do not set the set property. If the type of this attribute is string, it can also be unspecified. The properties of the type are used to automatically convert the property initial values that are configured in the specification file or in the template file. default
Properties are generally used as a reference and optional. If a property is readable and has not been set before, the Getter method should return a default value.
You can define component properties for a component with the following syntax:
<?xml version= "1.0" encoding= "UTF-8"?>
<component>
......
<component type= "component Type" id= "Component ID" >
<property name= ' property name ' value= ' property value '/>
....
<event name= "event name" handler= "function name"/>
....
</component>
......
</component>
Here the type attribute indicates the name of the component class, and the IDID attribute indicates the property name. The property element and the event element indicate the corresponding initial value.
When a component is created, its component type attributes are automatically instantiated.
2.4.2 Defining Events
Component events are defined in the specification file, and the intrinsic implementation mechanism is defined in the class file. The syntax for defining events in the specification file is as follows:
<?xml version= "1.0" encoding= "UTF-8"?>
<component>
......
<event name= "..."/>
......
</component>
The name of the event should be a valid variable name.
In a class file, a corresponding method is usually implemented (assuming that the name of the event is OnClick):
function OnClick ($param)
{
$this->raiseevent (' OnClick ', $this, $param);
}
When this event actually occurs, the OnClick method should indeed be invoked (reference frame of the tbutton.php
file). The RaiseEvent method is implemented in the Tcomponent class, which invokes all the event response functions corresponding to the OnClick and passes the parameters $param to them.
2.4.3 Writing template Files
In this section, you'll talk about how to write a template file. Templates are used for controls, and not all controls require a template at that time. Like ttextbox, TButton These controls do not require a template because they have no content. Template files are typically used for pages or for controls that are based on a combination definition.
Comments in the template, such as <!--...--> are treated as static text.
You can configure the properties of a component in addition to the component label by using the property label <prop:...> . For example, you can use the following code to configure the Text property of the Ttextbox control in the template.
...
<com:ttextbox id= "Profile" >
<prop:Text>
...
</prop:Text>
</com:TTextBox>
...
The content in the middle of a pair of property labels is the value of the corresponding component property. This is convenient if the values of some properties require large data.
You can use 3 special tags in the template file:
- <%include ...%> -the framework will contain an external file in this location before parsing the template. For example, you can use it to include a common header file <%include header.tpl%> in a page template. The path to the external file should be the relative path to the template file.
- <%= ...%> -will output the value of a PHP expression directly in this position, such as <%= date (' y-m-d ', Time ())
%>. Note that you do not need to enter a semicolon after an expression. The context of this expression is the corresponding component of this template, and you can use the component in an expression using $this variable. The value of an expression is evaluated when the component is drawn.
- <% ...%> -Represents a series of PHP statements. If they have either echo or print, the results are displayed in the corresponding position of the label. Note that the PHP statements here need to be separated by semicolons, and the standard PHP syntax is the same. Again, the context here is still the component that owns the template file. (Translator Note: Many places refer to contextual contexts, which are translated in some object-oriented books and sometimes translated into other languages.) It refers to which component $this is represented in the current code. Because a component may contain other components, such as a page that often contains many components, if the template is the page class, then our context is this page. Sometimes, for example, when we bind data to a component in a page, the context changes to the component, and$this represents the component, not the page. In the template file, other kinds of labels are free to use in addition to the component label range.
2.5 Summary
In this section we will summarize how to develop a Web application based on Prado.
First you need to create two files: The application's Portal file and the application's configuration file. Please refer to "hellow,world!" in front of this manual for this section This example.
For a complete Web application, you will also need to create one or more pages. Each page needs to have a page class file, and you may need a template file or a specification file. In a template file, you can organize components and other static text in the same way that you want to display them to the user at the end. In the specification file, you can define properties, events, and child controls for the page, which can be used in template files and code. Both can set the component's initial value and specify the response function for the event. Write event response functions and other functions in the page class file.
Sometimes, in order to reuse code, you can define new components. For example, you can set a SideBar component to display the menu that the user can see, so that the SideBar component can be used to display the menu directly on each page.
Prado introduced a new exception handling mechanism for PHP5 to display error messages on the stack. This way you can find out exactly what is wrong with the method when debugging.
Publishing PRADO applications is very simple. The framework recommends using a relative path, so if you do this, simply copy the code that contains your application to the directory you want to place.