I have seen hooks in Kohana PHP framework, and they work as some sort of a callback function triggered by a certain event (Kohana's events that is, some sort of method overloading).
I have seen hooks in Wordpress, and I don't know what they are or how to use them (just saw them yesterday).
I'm looking for events in "non-frameworked" php, I cannot find ones.
Do hooks work only in an "event-based" environment? What are they anyway (in general, not just in PHP)? What are they good for if not in an "event-based" environment.
Hooks are, indeed, hooks into an event stack of sorts; a list of values some controller iterates over, and if you have anything registered to that event, the controller can run your custom code. But PHP itself doesn't have anything (useful) like that, so you make it yourself or use the ones you find in your favorite application / system. It's a fairly common way to create a plugin architecture, but can also be used for application control and other things. I've written earlier about my quest for a more universal event and operating set of stack events, including this post here on StackOverflow.
As others have mentioned, PHP is stateless, so where I use them I use them as a simple execution list, and hook every part of my application into it. This way I'm very extensible, and have a basis for a plugin stack as well. (And I'll release it one magical day when I'm bored or retired or just got too much time on my hands, etc.)
You'll find similar stacks and hooks in, for example, WordPress, so a plugin that deals with, say, CSS, will hook itself to the CSS_DEFINITION_EVENT (basically, that part of the WordPress application that writes CSS stuff into the HTML section). This stuff is everywhere. In PHP it only applies (well, mostly) to the limits of the request you get per PHP page (unless you're doing PHP outside the webserver), but all major operating systems, applications, frameworks and systems have some form of event stack. PHP just doesn't have one (seriously) built in.
PHP is stateless, therefore it cannot really have events. They are emulated with manually adding and storing event listeners ( functions to be called ) and then calling said listeners explicitly when something happens in the code. Like a new picture was uploaded or a 404 error occurred.
Are you looking for these?
register_shutdown_function
set_error_handler
set_exception_handler
Related
I have recently look into observable pattern and I understand how things work and the concept. I also played with it in my application but I want to find out how to use it when you want to make a plugin in a php application, because that was my main purpose.
I haven't found any decent example until now. I want to understand the concept of making plugin with observable and also a good and easy example would be nice.
By making a plugin I mean to have a standard application and want to do some particular stuff for every client, because not all the clients ask the same things I can't give them all the same application, so the ideas so to make a standard application and configure it for every client and I understand that something like that is called to make a plugin and It can be done with observer.
Observer/Observable pattern would be a good fit if you want to implement some kind of custom triggers/actions based on user or application/service actions.
For example, an identity/authentication service might implement a pluggable architecture using some kind of observer to let third-party plug-ins do something when some user authenticates, or some user is registered...
Also it should work in the UI, because you might be able to show a menu or add some visual component based on user interaction.
If you want to make a very free plugin based application, you might want to do a slightly different version of this.
Implement a centralized event control.
Each Plugin (serving as your controllers) registers there to be notified for certain events.
Now if you want to access some functionality, just dispatch a specific event through that central event control. You no longer need to know what plugin will respond to your event, you only need to know the interface of said event and the form of response you will get.
Now multiple plugins can register on a event, overriding or extending the results of other plugins. Or just allow completely new events.
This application structure takes a bit of patience to properly create all needed classes, but the end product is extremely decoupled -> flexible. Think of it as a form of MVC where the controller(s) dont need to know each other, they just know where to ask in a very generic form.
(I heard Zend2 tries a similar approach?)
Anybody knows reasonable hooks usage? I wrote 2 projects and have no idea what the used for.
Thanks
Hooks in CodeIgniter are used to extend or override the core functionality -- for example:
EXTEND:
If you want to add some basic analytics to your page you might add a pre_system and a post_system hook to log the length of time the request took (or at least, how long CodeIgniter took to process the request) and to record the requested URL, the user, and the time. (The first part of this hook series could be handled better by the Benchmark class, since it is already loaded).
OVERRIDE:
From the documentation:
cache_override
Enables you to call your own function instead of the _display_cache() function in the output class. This permits you to use your own cache display mechanism.
From CodeIgniter User Guide Version 2.1.4
CodeIgniter's Hooks feature provides a means to tap into and modify the inner workings of the framework without hacking the core files. When CodeIgniter runs it follows a specific execution process, diagramed in the Application Flow page. There may be instances, however, where you'd like to cause some action to take place at a particular stage in the execution process. For example, you might want to run a script right before your controllers get loaded, or right after, or you might want to trigger one of your own scripts in some other location.
Not sure what you consider "reasonable" though, but the above summarizes it pretty well. They allow you to add additional behavior to core library classes at various points in the execution cycle.
I'm starting to architect a quite complex web application. The implementation is probably going to be done in PHP, though if there are impressive reasons to choose a different environment I might be convinced.
I've looked at tools like Symfony and CakePHP. The problem is that it feels like they're relatively low level for a modern Web 2.0 application. They handle the basic things like MVC and scaffolding, but not the more advanced UI elements that I'm looking for. Here are some of my requirements:
Single page architecture. With minor exceptions, there should be no page refresh. All actions are done via ajax, the way it's done in gmail, and to a lesser extent in Facebook.
Ajax layout and widget handling. Not only the application doesn't refresh the page, but the developer can specify the layout and load various widgets into different parts of the page. This is somewhat like iGoogle, but should be better integrated.
Support both on the client side and server side for AJAX widgets. It should be trivial to display the result of a select statement in an AJAX table/array like http://developer.yahoo.com/yui/datatable/. This should also apply to other widgets including
Trees
Menus
Forms
Speaking of forms, there should be easy integration with client side validation
Signup/Authentication/Authorization. Including all the housekeeping things like forgot my password, CAPTCHAs, etc.
There's more, but I think I've given enough details so that you get an idea for what I'm looking for. Basically, I'd like to engineer a modern Web 2.0 app and skip writing, testing, debugging things that most web applications need to do. And yes, I know I can take YUI or jQuery and slap it on top of one of the regular platforms, but then I'd have to write all the glue. Now if there are modules that do this, that would be interesting.
So if you say, take Symfony + modules xyz + jQuery and there's your answer, I'd be happy to hear that.
Finally, in terms of priority, I'm looking for something that's scalable, reliable, well engineered more than something that's easy to learn and deploy.
Since you are looking for all things AJAX, why not try GWT? Its not PHP I agree, but it makes writing AJAX applications easy for developers.
I agree with #Iznogood. What your looking for is not actually a framework but a talent.You can make any framework as "igoogle-ish" as possible if you know what your doing.
I suggest look for a framework with a huge and active community like, CI, Cake and Jquery. Search/ask the community for the specific things you need. Plug it in and Presto!
But I'm afraid you'll have to write some of it.
If you don't mind using Java, there is ZK:
http://www.zkoss.org/
I'd prefer using this over GWT.
In php, you might want to consider Cjax http://cjax.sourceforge.net/.
It is MVC oriented, and has a very generic API, with full support for customization, including the development of plugins (There is a full Plugin API available, including documentation, Plugins can be built in PHP and JavaScript in combination -- see uploadify and validate plugins).
It can access all JavaScript functions, Objects and proprieties, and elements properties and functions from PHP server side, with one line of code.
In Cjax,
you can execute ajax actions, inside controllers (ajax requests) - without a line of JavaScript. this allows you to fully function without refreshing the page. It also allows you to access all Js objects from PHP. A good sample that reflects this is the "recursive ajax request" see that demo. The API can be used on page load, when the page first loads, and within every single ajax request.
Do take a look at the documentation and to the 20+ demos included, and no where you will see a single line of JavaScript. It allows you to manipulate elements, containers, request ajax, submit ajax forms, creates overlays, upload files through ajax, all from the server side. Take a glace at the API Table.
It has support for both, server side ajax, and client side, (see plugins JavaScript Documentation)
It plays nice with jQuery - the validation plugin in jquery is full executable in PHP without a line of JavaScript (see http://cjax.sourceforge.net/examples/plugin_validate.php without any custom line of Jquery inside the framework, it's all plugin's work). Ajax Responses from Jquery also get processed by this framework automatically, so using Jquery's Ajax function API wise, is the same as if you were using the Framework's Plugin's JavaScript Ajax Functions.
And you would just have to take your time learning more about it, because it has quite a few more tools that I am sure you'd find useful.
Currently there are two official releases, the generic release and
there is an official release for CodeIgnater of this framework (and it is the leading ajax option for codeignater) , and works great in conjunction other PHP Frameworks and without them.
Signup/Authentication/Authorization. Including all the housekeeping
things like forgot my password, CAPTCHAs, etc.
This is something that you can build within an ajax controller, the framework itself its meant to be a generic "AJAX" framework, so if you are looking for none ajax features, you will need to build them or integrate other PHP Framework with Cjax (such as Codeignater).
I do not know if this matches all of your criteria, or if you ever will find one. However, I like the Zend Framework myself.
As for the UI and AJAX portions - the server side technology matters little, and it's more about browser-side technology and interaction mechanisms, as well as DOM manipulation.
jQuery is my favorite for that. As for the PHP back-end, I tend to develop it with my own codebase that's grown with me over the years.
But all this takes a lot of practice, knowledge, education, research, reading, and posting questions on StackOverflow.com ;)
I would recommend symfony PHP framework since it has very good support for every feature you mentioned, and it can be easily integrated with Zend Framework - as of version 2.0 coming this year it would be integrated in the package. You can easily set symfony to handle AJAX requests so that it would be perfect transparent layer handling server side.
For me, if you look at THAT heavy AJAX, I would recommend searching for some good JavaScript framework - such as Ext.JS - that would handle all client side functionalities.
For the front-end part of your app, you might want to have a look at SproutCore ( http://www.sproutcore.com/ ).
Building a Web application with SproutCore feels more like configuring components than writing code.
There is no glue code.
On the backend all you have to do is accept and emit JSON.
Depends what sort of level you're looking at. If by 'framework' you mean something like Zend or Symphony, then to be honest all the big ones are about as good as each other. They all have strong points and weak points, but none will really meet your criteria.
But your question implies you're looking for something more than that kind of framework. Maybe you're looking for a full-blown CMS platform like Drupal, Joomla or Wordpress?
In that case, again, you need to consider your needs verses the capabilities and pitfalls of each system.
Drupal, for example, has masses of modules, is very powerful, and easy to write your own modules, but isn't object-oriented and doesn't really do MVC, so if that's your bag then you may find it hard to get on with. Wordpress is much easier to get going quickly but is less flexible once you start getting deeper into it.
But again, they all have strengths and weaknesses. If one was clearly the best, it would be an easy choice. But at the end of day perhaps it's better to have several good quality options to choose from.
Have a look at Ext JS, it is pretty good. If it is a commercial project you are doing it isn't free but not too expensive either. It also has a GWT version if you prefer that.
This is only for the front end but it is not too complicated to use any backend that can emit json.
CakePHP is pretty good
I'm trying to identify some of the pros and cons of having a CMS that is event driven.
Event driven is not uncommon. You see it in many scripting languages like Actionscript, javascript, jquery that involve a client. How about in a CMS where the events and their responses happen on the server. What advantages or disadvantages might this approach have, and what other approaches are there that people may prefer more.
P.S. Please note that I use Actionscript, JQ, and JS as an example only. You realize that when talking about a CMS this way, the events an their responses are all server side stuff.
Edit: I see a lot of people saying that it makes no sense to use event-driven as they don't get what it is. One of the CMS systems that already use this approach is Drupal, so trust me it's an existing way, I'm not pulling ideas out of my A. It just means the "internals" of the CMS (all the server-side stuff) are event-driven. The core does its thing AND defines events. Plugins can respond to those events to add their own logic. I mentione Actionscript as an example because client-side is where this concept is most known, but it can be on the server-side too, just maybe not as relevant for normal applications and so not as known. But it makes sense for something more complex like a CMS where other developers want to add their own plugins or even change the pre-built in logic of the CMS.
Are you sure "event-driven" is the correct term for this?
I think what you are talking about is a plugin hook infrastructure that allows plugins to act when an event takes place (a hook is triggered).
What I know as "event driven" is when desktop applications store events in UI elements, just as Javascript can do for HTML elements. Desktop apps are built entirely that way. That can never be achieved in Web-based PHP because it is entirely request oriented.
Anyway, I see what you mean now. There are CMSs and frameworks that have this to some extent - Wordpress for example and Dokuwiki.
In Wordpress, these events are called actions. You can see a full list in the Wordpress Plugin API.
In DokuWiki, they are indeed called events: DokuWiki's event system
In addition:
I'm trying to identify some of the pros and cons of having a CMS that is event driven.
The pros are obvious: It becomes much, much easier to hook into the system without having to hack the core. It becomes possible to write real plugins.
One big con is that the system tends to become slower on the long term the more hooks there are, and the more plugins are registered to the hooks. I've seen a huge portal's maintenance operation - the deletion of several hundred Drupal nodes - take hours on a ultra-fast production server, mainly because of the hook system.
What exactly do you mean by "event driven"? Does it mean, that clients can watch content and will be notified, when it is updated?
If so, than this is really a great idea, but the implementation is an ambitous undergoing. The clear disadvantage is, that there are tons of things, that can go wrong, while a request based model is much simpler and thus more robust.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
Could someone provide a architectural overview of the Drupal 7 control flow? Perhaps in the sense of a flowchart about how a page gets generated. What additional resources would you suggest consulting with regards to how Drupal works?
Drupal can be confusing on this front, partially because it has a relatively deep function stack. Although it's procedural PHP it's purely event/listener driven in its architecture, and there's no simple "flow" in the main PHP script for you to look though. I recently did a presentation on this very subject, and the slides are posted on slideshare, but a quick high-level summary may be useful.
Drupal's index.php file functions as a frontside controller. All page are piped through it, and the "actual" url/path the user requested is passed to index.php as a parameter.
Drupal's path router system (MenuAPI) is used to match the requested path to a given plugin module. That plugin module is responsible for building the "primary content" of the page.
Once the primary page content is built, index.php calls theme('page', $content), which hands off the content to Drupal's theming/skinning system. There, it's wrapped in sidebars/headers/widgets/etc..
The rendered page is then handed back to apache and it gets sent back to the user's browser.
During that entire process, Drupal and third-party plugin modules are firing off events, and listening for them to respond. Drupal calls this the 'hook' system, and it's implemented using function naming conventions. The 'blog' module, for example, can intercept 'user' related by implementing a function named blog_user(). In Drupal parlance, that's called hook_user().
It's a bit clunky, but due to a PHP quirk (it keeps an internal hashtable of all loaded functions), it allows Drupal to quickly check for listeners just by iterating over a list of installed plugins. For each plugin it can call function_exists() on the appropriately named pattern, and call the function if it exists. ("I'm firing the 'login' event. Does 'mymodule_login' function exist? I'll call it. Does 'yourmodule_login' exist? No? How about 'nextmodule_login'?" etc.) Again, a touch clunky but it works pretty well.
Everything that happens in Drupal happens because of one of those events being fired. The MenuAPI only knows about what urls/paths are handled by different plugin modules because it fires the 'menu' event (hook_menu) and gathers up all the metadata plugin modules respond with. ("I'll take care of the url 'news/recent', and here's the function to call when that page needs to be built...") Content only gets saved because Drupal's FormAPI is responsible for building a page, and fires the 'a form was submitted' event for a module to respond to. Hourly maintenance happens because hook_cron() is triggered, and any module with mymodulename_cron() as a function name will have its function called.
Everything else is ultimately just details -- important details, but variations on that theme. index.php is the controller, the menu system determins what the "current page" is, and lots of events get fired in the process of building that page. Plugin modules can hook into those events and change the workflow/supply additional information/etc. That's also part of the reason so many Drupal resources focus on making modules. Without modules, Drupal doesn't actually DO anything other than say, 'Someone asked for a page! Does it exist? No? OK, I'll serve up a 404.'
To understand how Drupal works, you need to understand Drupal's page serving mechanism.
In short, all the calls/urls/requests are served by index.php which loads Drupal by including various include files/modules and then calling the appropriate function, defined in module, to serve the request/url.
Here is the extract from the book, Pro Drupal Development, which explains the Drupal's bootstrap process,
The Bootstrap Process
Drupal bootstraps itself on every request by going through a series of bootstrap phases. These phases are defined in bootstrap.inc and proceed as described in the following sections.
Initialize Configuration
This phase populates Drupal’s internal configuration array and establishes the base URL
($base_url) of the site. The settings.php file is parsed via include_once(), and any variable or string overrides established there are applied. See the “Variable Overrides” and “String Overrides” sections of the file sites/all/default/default.settings.php for details.
Early Page Cache
In situations requiring a high level of scalability, a caching system may need to be
invoked before a database connection is even attempted. The early page cache phase lets
you include (with include()) a PHP file containing a function called page_cache_
fastpath(), which takes over and returns content to the browser. The early page cache
is enabled by setting the page_cache_fastpath variable to TRUE, and the file to be included
is defined by setting the cache_inc variable to the file’s path. See the chapter on caching
for an example.
Initialize Database
During the database phase, the type of database is determined, and an initial connection is
made that will be used for database queries.
Hostname/IP-Based Access Control
Drupal allows the banning of hosts on a per-hostname/IP address basis. In the access control
phase, a quick check is made to see if the request is coming from a banned host; if so,
access is denied.
Initialize Session Handling
Drupal takes advantage of PHP’s built-in session handling but overrides some of the handlers
with its own to implement database-backed session handling. Sessions are initialized
or reestablished in the session phase. The global $user object representing the current user
is also initialized here, though for efficiency not all properties are available (they are added by an explicit call to the user_load() function when needed).
Late Page Cache
In the late page cache phase, Drupal loads enough supporting code to determine whether or
not to serve a page from the page cache. This includes merging settings from the database into the array that was created during the initialize configuration phase and loading or parsing module code. If the session indicates that the request was issued by an anonymous user and page caching is enabled, the page is returned from the cache and execution stops.
Language Determination
At the language determination phase, Drupal’s multilingual support is initialized and a decision is made as to which language will be used to serve the current page based on site and user settings. Drupal supports several alternatives for determining language support, such as path prefix and domain-level language negotiation.
Path
At the path phase, code that handles paths and path aliasing is loaded. This phase enables
human-readable URLs to be resolved and handles internal Drupal path caching and
lookups.
Full
This phase completes the bootstrap process by loading a library of common functions, theme
support, and support for callback mapping, file handling, Unicode, PHP image toolkits, form
creation and processing, mail handling, automatically sortable tables, and result set paging. Drupal’s custom error handler is set, and all enabled modules are loaded. Finally, Drupal fires the init hook, so that modules have an opportunity to be notified before official processing of the request begins.
Once Drupal has completed bootstrapping, all components of the framework are available.
It is time to take the browser’s request and hand it off to the PHP function that will
handle it. The mapping between URLs and functions that handle them is accomplished using
a callback registry that takes care of both URL mapping and access control. Modules register
their callbacks using the menu hook (for more details, see Chapter 4).
When Drupal has determined that there exists a callback to which the URL of the browser
request successfully maps and that the user has permission to access that callback, control is handed to the callback function.
Processing a Request
The callback function does whatever work is required to process and accumulate data needed to fulfill the request. For example, if a request for content such as http://example.com/
q=node/3 is received, the URL is mapped to the function node_page_view() in node.module.
Further processing will retrieve the data for that node from the database and put it into a data structure. Then, it’s time for theming.
Theming the Data
Theming involves transforming the data that has been retrieved, manipulated, or created
into HTML (or XML or other output format). Drupal will use the theme the administrator
has selected to give the web page the correct look and feel. The resulting output is then sent to the web browser (or other HTTP client).
Eaton's answer provides a good overview. (I'm new here so I can't mod him up, thus the comment.)
The brutal "aha" moment for me was realizing everything happens through index.php, and then through the waterfall of modules (core first, then by site). To extend core functionality don't rewrite it. Instead copy the module into /sites/all/modules/ or /sites/[yoursite]/modules and extend THAT, or create a new module in those places. Same for themes. Module directories can contain display code as well, in the form of tpl, css etc.
If you're used to stricter MVC type frameworks like Rails, Django etc. all this gets a little confusing. Modules can mix in a lot of display code, and if you're looking at someone else's modules or templates you'll eventually wind up walking backwards through the stack. That's the beauty/pain of working in PHP.
Ironically, "just build an app" might be the worst way to learn this. Drupal does so much out of the box that's simply obscure until you figure out the control flow. There's nothing in a tpl file that tells you where a function with a fun name like l() comes from, for example.
It depends on how deep an understanding you're looking for; if you have a good knowledge of php, I would suggest reading through the code itself, starting with index.php, and then going on to the includes/bootstrap.inc, and then some of the other scripts in that directory.
The key include files:
menu.inc is very important to understanding how the overall system works, as it handles a lot of the implicit mapping of URLs to content.
common.inc has most of the otherwise-mysterious functions that form the basis of the API.
module.inc handles the hook invocations that Eaton mentioned
form.inc deals with form display, submission and processing
theme.inc handles presentation.
There's also some key functionality in the modules/ directory; in particular, modules/node/node.module forms the basis of the node system, which is in general what's used to encapsulate site content.
The code is, in general, very well-commented and clear. The use of Doxygen markup within the commenting means that the code effectively is the canonical documentation.
It also helps to do this using an editor that can quickly jump to the definition of a function. Using vim in combination with ctags works for me; you do have to tell ctags to index .inc, .module, etc. files as php files.
This (for Drupal 6) & this (for Drupal 7) is a pretty good architectural overview of drupal. If you want more detail then I would start writing something most of the documentation is good. Trying to learn it at a high level of detail without something concrete to achieve will be much more difficult that trying something out.
I learned loads by importing the drupal .php code into a NetBeans project.
You can then run the netbeans debugger and watch the different phases of the page come together.
The best books on the subject are "Pro Drupal Development" and "Using Drupal."
"Pro Drupal Development" includes several nice flowcharts and thorough summaries of each of Drupal's APIs (forms, theming, etc.). It's intended to be especially instructive to people making their own modules and themes, but has lots of value to the average PHP-savvy developer who wants to understand Drupal. Besides which, I've created a custom module for every site I've built, just to gain the extra control over things like selectively hiding fields on various forms (which you generally want to do for the sake of simplifying node forms for end-users), so it's good to have this knowledge under your hat.
"Using Drupal" is aimed at the site developer who wants to know how to build the good stuff like galleries, blogs, and social networking sites. It goes through several use-cases and shows how to configure existing modules to do each job. In the process it familiarizes you with the essential add-on modules "Content Construction Kit" (CCK) and "Views," how to make custom blocks and templates, and the ins-and-outs of maintaining a Drupal site. I recommend this book especially for those who want to get up to speed and actually USE Drupal right away. In the process you gain an understanding of the internal organization of Drupal.
New contributor here, 2 years late on the conversation ;-)
Replying to https://stackoverflow.com/a/1070325/1154755
To extend core functionality don't rewrite it. Instead copy the module
into /sites/all/modules/ or /sites/[yoursite]/modules and extend
THAT, or create a new module in those places. Same for themes.
Actually, I never had to copy a core module to update it. Drupal Hooks should be all you need.
For themes, yeah, sometimes it's the only way to go, but often, you can build a subtheme to get the result you need.