About cookies

Items 1 to 20 of 40 total

per page

Set Ascending Direction
  • ]project-open[ V3.4 的新改变!

    9 year(s) ago

    很抱歉由于时间太匆忙,我们(CosmoCommerce)仅仅翻译了部分介绍信息.如果有时间我们会进一步编辑本文,完善翻译.请保持对本文的跟踪.
    
    ]project-open[ V3.4 更新了什么?
    
    版本 V3.4 是18个月来的新版本.包括了大量功能增强和改进.
    
    非功能改进
    Windows Linux的安装包: 从 V3.4 开始, ]po[ 完全支持 Windows
    作为生产环境. 新的 Windows 安装程序简化了很多用户的使用. Linux 的安装程序是针对 Red Hat Enterprise Linux 5/CentOS 5,
    Debian 和 Ubuntu. Mac OSX 很快将会完成.
    
    新的图形人机界面: ]project-open[ 已经完全重新设计了人机界面.新的GUI特性包括多个自定制CSS皮肤和一个可伸缩的功能菜单.
    新的语言支持: ]project-open[ GUI 现在支持翻译为阿拉伯语,中文简体,德语,英语,法语,荷兰语,意大利语,日语,葡萄牙语(巴西),俄语,西班牙语和土耳其语.
    New Documentation Wiki & Context Help: We have created a Wiki at
    www.project-open.org/ with more than 500 pages of online documentation. The
    Wiki is integrated with the ]po[ application, providing online help for ]po[
    administration screens, “categories,” reports and performance indicators.
    All other screens will be updated in V4.0.
    
    Performance Improvements for Large Installations: New cache functions for
    frequently used queries and a number of SQL optimizations have improved
    performance in large installations with more than 1.000 active users.
    
    Audit Package: A new package makes it possible to track modifications to all
    important business objects in the system, implementing requirements for a
    number of security and compliance regulations. The package is available as a
    commercial enterprise add-on and is not part of the main distribution.
    
    新功能
    
    V3.4 includes a number of new packages. Most importantly, V3.4 now includes
    a generic help desk and general service management functionality. A number
    of optional add-on packages address the specific needs of IT organizations.
    
    Help Desk: The new package implements tickets and ticket queues. Help desk
    tickets can be extended with dynamic fields and with permissions per ticket
    type and user group. Custom Workflows can be defined per ticket type. The
    help desk package can be used to implement a variety of different processes
    ranging from order processing and CRM customer complaints to ITIL problem
    and change management. An integration with the Nagios systems management
    integration exists in order to import Nagios events into the Help desk.
    
    Inventory: The new package implements a company's inventory with a
    hierarchical is-part-of structure. Inventory items can be extended with
    dynamic fields with permissions per item type and user group. Inventory
    items can be related to projects and help desk tickets, allowing users to
    track changes and formalize acquisition and other item-related approval
    processes. The inventory package can be used to implement a variety of
    different processes ranging from general lab or company inventory to ITIL
    configuration and license management. An integration with OCS Inventory NG
    is available in order to inventorize IT assets, and an integration with the
    Nagios systems management system makes it possible to import Nagios servers
    into the inventory.
    
    ITIL Release Management: The new package implements a release management
    process compliant with ITIL. A number of Requests for Change and project
    tasks can be selected into a “release project” and need to pass tests and
    approval steps individually and as a whole. The package allows for
    compliance with Basel II and SOX regulations.
    
    Dynamic Workflows: The ]po[ Petri-Net Workflow was already part of V3.2,
    including its graphical editor. In V3.4 we have now extended the number of
    objects to which you can attach a workflow, and this version includes
    default workflows for budgets, projects, absences and timesheets.
    
    CVS & Host Version Control Integration: The new package can read log
    messages from CVS (additional version management systems will follow soon)
    and relate them to Configuration Items, projects and tickets. CVS logs
    including a ticket ID will automatically close the ticket.
    
    Automated RFQs for External Consultants: This new package allows for
    automated Request for Quotation and other auction types, in order to improve
    the communication with external consultants and other providers. RFQ
    requests and answer sheets can be customized via Dynamic Fields configurable
    per RFQ type.
    
    Key Performance Indicators: This new package provides a graphical display of
    performance indicators, showing the current value in a high/low watermark
    display and a historical diagram with the development of the indicator over
    time. The package includes some 25 sample indicators for finance, CRM and
    project management. New indicators can be added by the user via
    administration screens.
    
    新特性
    
    New Reports: We have added a number of reports and data-warehouse cubes.
    
    Timesheet Invoicing Wizard: The improved functionality now supports
    non-billable materials (type of service) and keeps track of unbilled hours
    in the current invoicing period and before.
    
    Improved Invoicing Screens: A new AJAX functionality allows for comfortable
    changing of invoicing offices and contacts when changing the customer.
    
    Financial Documents List Page: Pagination on this screen now improves
    performance. ­
    
    错误修复
    
    V3.4 修复了包括 150个错误和细节改进
    
    - http://www.project-open.org/ (开发者)
    - http://www.project-open.com/ (公司运营)
    - http://demo.project-open.net/ (范例)
    - http://sourceforge.net/projects/project-open/files/ (下载)
    - http://www.project-open.org/documentation/press_kit (官方发布资料)
    - http://www.project-open.org/documentation/project_open_roadmap (更新)
    - http://www.project-open.org/documentation/list_installers (安装)
    

  • 使用高效缓存来解决PHP性能问题 By Ben Balbo

    9 year(s) ago

    本文非常非常全面的介绍了PHP的各种缓存技巧,值得做性能优化的好好学习.
    
    由于本文非常的长,所以需要看全文可以点击:http://www.sitepoint.com/launch/108ef2/2/120
    
    或者查看其他章节:http://www.sitepoint.com/books/phpant2/toc.php
    
    In the good old days when building web sites was as easy as knocking up a few HTML pages, the delivery of a web page to a browser was a simple matter of having the web server fetch a file. A site's visitors would see its small, text-only pages almost immediately, unless they were using particularly slow modems. Once the page was downloaded, the browser would cache it somewhere on the local computer so that, should the page be requested again, after performing a quick check with the server to ensure the page hadn't been updated, the browser could display the locally cached version. Pages were served as quickly and efficiently as possible, and everyone was happy. 
    
    
    
    
    Then dynamic web pages came along and spoiled the party by introducing two problems:
    
    • When a request for a dynamic web page is received by the server, some intermediate processing must be completed, such as the execution of scripts by the PHP engine. This processing introduces a delay before the web server begins to deliver the output to the browser. This may not be a significant delay where simple PHP scripts are concerned, but for a more complex application, the PHP engine may have a lot of work to do before the page is finally ready for delivery. This extra work results in a noticeable time lag between the user's requests and the actual display of pages in the browser.
    • A typical web server, such as Apache, uses the time of file modification to inform a web browser of a requested page's age, allowing the browser to take appropriate caching action. With dynamic web pages, the actual PHP script may change only occasionally; meanwhile, the content it displays, which is often fetched from a database, will change frequently. The web server has no way of discerning updates to the database, so it doesn't send a last modified date. If the client (that is, the user's browser) has no indication of how long the data will remain valid, it will take a guess. This is problematic if the browser decides to use a locally cached version of the page which is now out of date, or if the browser decides to request from the server a fresh copy of the page, which actually has no new content, making the request redundant. The web server will always respond with a freshly constructed version of the page, regardless of whether or not the data in the database has actually changed.
    To avoid the possibility of a web site visitor viewing out-of-date content, most web developers use a meta tag or HTTP headers to tell the browser never to use a cached version of the page. However, this negates the web browser's natural ability to cache web pages, and entails some serious disadvantages. For example, the content delivered by a dynamic page may only change once a day, so there's certainly a benefit to be gained by having the browser cache a page--even if only for 24 hours. If you're working with a small PHP application, it's usually possible to live with both issues. But as your site increases in complexity--and attracts more traffic--you'll begin to run into performance problems. Both these issues can be solved, however: the first with server-side caching; the second, by taking control of client-side caching from within your application. The exact approach you use to solve these problems will depend on your application, but in this chapter, we'll consider both PHP and a number of class libraries from PEAR as possible panaceas for your web page woes. Note that in this chapter's discussions of caching, we'll look at only those solutions that can be implemented in PHP. For a more general introduction, the definitive discussion of web caching is represented by Mark Nottingham's tutorial. Furthermore, the solutions in this chapter should not be confused with some of the script caching solutions that work on the basis of optimizing and caching compiled PHP scripts, such as Zend Accelerator and ionCube PHP Accelerator. This chapter is excerpted from The PHP Anthology: 101 Essential Tips, Tricks & Hacks, 2nd Edition. Download this chapter plus two others, covering PDO and Databases, and Access Control, in PDF format to read offline.
    How do I prevent web browsers from caching a page?
    If timely information is crucial to your web site and you wish to prevent out-of-date content from ever being visible, you need to understand how to prevent web browsers--and proxy servers--from caching pages in the first place. Solutions There are two possible approaches we could take to solving this problem: using HTML meta tags, and using HTTP headers. Using HTML Meta Tags The most basic approach to the prevention of page caching is one that utilizes HTML meta tags: <meta http-equiv="expires" content="Mon, 26 Jul 1997 05:00:00 GMT"/> <meta http-equiv="pragma" content="no-cache" /> The insertion of a date that's already passed into the Expires meta tag tells the browser that the cached copy of the page is always out of date. Upon encountering this tag, the browser usually won't cache the page. Although the Pragma: no-cache meta tag isn't guaranteed, it's a fairly well-supported convention that most web browsers follow. However, the two issues associated with this approach, which we'll discuss below, may prompt you to look at the alternative solution. Using HTTP Headers A better approach is to use the HTTP protocol itself, with the help of PHP's header function, to produce the equivalent of the two HTML meta tags above: <?php header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Pragma: no-cache'); ?> We can go one step further than this, using the Cache-Control header that's supported by HTTP 1.1-capable browsers: <?php header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0', FALSE); header('Pragma: no-cache'); ?> For a precise description of HTTP 1.1 Cache-Control headers, have a look at the W3C's HTTP 1.1 RFC. Another great source of information about HTTP headers, which can be applied readily to PHP, is mod_perl's documentation on issuing correct headers. Discussion Using the Expires meta tag sounds like a good approach, but two problems are associated with it:
    • The browser first has to download the page in order to read the meta tags. If a tag wasn't present when the page was first requested by a browser, the browser will remain blissfully ignorant and keep its cached copy of the original.
    • Proxy servers that cache web pages, such as those common to ISPs, generally won't read the HTML documents themselves. A web browser might know that it shouldn't cache the page, but the proxy server between the browser and the web server probably doesn't--it will continue to deliver the same out-of-date page to the client.
    On the other hand, using the HTTP protocol to prevent page caching essentially guarantees that no web browser or intervening proxy server will cache the page, so visitors will always receive the latest content. In fact, the first header should accomplish this on its own; this is the best way to ensure a page is not cached. The Cache-Control and Pragma headers are added for some degree of insurance. Although they don't work on all browsers or proxies, the Cache-Control and Pragma headers will catch some cases in which the Expires header doesn't work as intended--if the client computer's date is set incorrectly, for example. Of course, to disallow caching entirely introduces the problems we discussed at the start of this chapter: it negates the web browser's natural ability to cache pages, and can create unnecessary overhead, as new versions of pages are always requested, even though those pages may not have been updated since the browser's last request. We'll look at the solution to these issues in just a moment.
    How do I control client-side caching?
    We addressed the task of disabling client-side caching in "How do I prevent web browsers from caching a page?", but disabling the cache is rarely the only (or best) option. Here we'll look at a mechanism that allows us to take advantage of client-side caches in a way that can be controlled from within a PHP script. Apache Required! This approach will only work if you're running PHP as an Apache web server module, because it requires use of the function getallheaders--which only works with Apache--to fetch the HTTP headers sent by a web browser. Solutions In controlling client-side caching you have two alternatives. You can set a date on which the page will expire, or respond to the browser's request headers. Let's see how each of these tactics is executed. Setting a Page Expiry Header The header that's easiest to implement is the Expires header--we use it to set a date on which the page will expire, and until that time, web browsers are allowed to use a cached version of the page. Here's an example of this header at work: expires.php (excerpt) <?php function setExpires($expires) { header( 'Expires: '.gmdate('D, d M Y H:i:s', time()+$expires).'GMT'); } setExpires(10); echo ( 'This page will self destruct in 10 seconds<br />' ); echo ( 'The GMT is now '.gmdate('H:i:s').'<br />' ); echo ( '<a href="'.$_SERVER['PHP_SELF'].'">View Again</a><br />' ); ?> In this example, we created a custom function called setExpires that sets the HTTP Expires header to a point in the future, defined in seconds. The output of the above example shows the current time in GMT, and provides a link that allows us to view the page again. If we follow this link, we'll notice the time updates only once every ten seconds. If you like, you can also experiment by using your browser's Refresh button to tell the browser to refresh the cache, and watching what happens to the displayed date. Acting on the Browser's Request Headers A more useful approach to client-side cache control is to make use of the Last-Modified and If-Modified-Since headers, both of which are available in HTTP 1.0. This action is known technically as performing a conditional GET request; whether your script returns any content depends on the value of the incoming If-Modified-Since request header. If you use PHP version 4.3.0 and above on Apache, the HTTP headers are accessible with the functions apache_request_headers and apache_response_headers. Note that the function getallheaders has become an alias for the new apache_request_headers function. This approach requires that you send a Last-Modified header every time your PHP script is accessed. The next time the browser requests the page, it sends an If-Modified-Since header containing a time; your script can then identify whether the page has been updated since that time. If it hasn't, your script sends an HTTP 304 status code to indicate that the page hasn't been modified, and exits before sending the body of the page. Let's see these headers in action. The example below uses the modification date of a text file. To simulate updates, we first need to create a way to randomly write to the file: ifmodified.php (excerpt) <?php $file = 'ifmodified.txt'; $random = array (0,1,1); shuffle($random); if ( $random[0] == 0 ) { $fp = fopen($file, 'w'); fwrite($fp, 'x'); fclose($fp); } $lastModified = filemtime($file); Our simple randomizer provides a one-in-three chance that the file will be updated each time the page is requested. We also use the filemtime function to obtain the last modified time of the file. Next, we send a Last-Modified header that uses the modification time of the text file. We need to send this header for every page we render, to cause visiting browsers to send us the If-Modifed-Since header upon every request: ifmodified.php (excerpt) header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT'); Our use of the getallheaders function ensures that PHP gives us all the incoming request headers as an array. We then need to check that the If-Modified-Since header actually exists; if it does, we have to deal with a special case caused by older Mozilla browsers (earlier than version 6), which appended an illegal extra field to their If-Modified-Since headers. We use PHP's strtotime function to generate a timestamp from the date the browser sent us. If there's no such header, we set this timestamp to zero, which forces PHP to give the visitor an up-to-date copy of the page: ifmodified.php (excerpt) $request = getallheaders(); if (isset($request['If-Modified-Since'])) { $modifiedSince = explode(';', $request['If-Modified-Since']); $modifiedSince = strtotime($modifiedSince[0]); } else { $modifiedSince = 0; } Finally, we check to see whether or not the cache has been modified since the last time the visitor received this page. If it hasn't, we simply send a 304 Not Modified response header and exit the script, saving bandwidth and processing time by prompting the browser to display its cached copy of the page: ifmodified.php (excerpt) if ($lastModified <= $modifiedSince) { header('HTTP/1.1 304 Not Modified'); exit(); } echo ( 'The GMT is now '.gmdate('H:i:s').'<br />' ); echo ( '<a href="'.$_SERVER['PHP_SELF'].'">View Again</a><br />' ); ?> Remember to use the "View Again" link when you run this example (clicking the Refresh button usually clears your browser's cache). If you click on the link repeatedly, the cache will eventually be updated; your browser will throw out its cached version and fetch a new page from the server. If you combine the Last-Modified header approach with time values that are already available in your application--for example, the time of the most recent news article--you should be able to take advantage of web browser caches, saving bandwidth and improving your application's perceived performance in the process. Be very careful to test any caching performed in this manner, though; if you get it wrong, you may cause your visitors to consistently see out-of-date copies of your site. Discussion HTTP dates are always calculated relative to Greenwich Mean Time (GMT). The PHP function gmdate is exactly the same as the date function, except that it automatically offsets the time to GMT based on your server's system clock and regional settings. When a browser encounters an Expires header, it caches the page. All further requests for the page that are made before the specified expiry time use the cached version of the page--no request is sent to the web server. Of course, client-side caching is only truly effective if the system time on the computer is accurate. If the computer's time is out of sync with that of the web server, you run the risk of pages either being cached improperly, or never being updated. The Expires header has the advantage that it's easy to implement; in most cases, however, unless you're a highly organized person, you won't know exactly when a given page on your site will be updated. Since the browser will only contact the server after the page has expired, there's no way to tell browsers that the page they've cached is out of date. In addition, you also lose some knowledge of the traffic visiting your web site, since the browser will not make contact with the server when it requests a page that's been cached.
    How do I examine HTTP headers in my browser?
    How can you actually check that your application is running as expected, or debug your code, if you can't actually see the HTTP headers? It's worth knowing exactly which headers your script is sending, particularly when you're dealing with HTTP cache headers. Solution Several worthy tools are available to help you get a closer look at your HTTP headers: LiveHTTPHeaders This add-on to the Firefox browser is a simple but very handy tool for examining request and response headers while you're browsing. Firebug Another useful Firefox add-on, Firebug is a tool whose interface offers a dedicated tab for examining HTTP request information. HTTPWatch This add-on to Internet Explorer for HTTP viewing and debugging is similar to LiveHTTPHeaders above. Charles Web Debugging Proxy Available for Windows, Mac OS X, and Linux or Unix, the Charles Web Debugging Proxy is a proxy server that allows developers to see all the HTTP traffic between their browsers and the web servers to which they connect. Any of these tools will allow you to inspect the communication between the server and browser.
    How do I cache file downloads with Internet Explorer?
    If you're developing file download scripts for Internet Explorer users, you might notice a few issues with the download process. In particular, when you're serving a file download through a PHP script that uses headers such as Content-Disposition: attachment, filename=myFile.pdf or Content-Disposition: inline, filename=myFile.pdf, and that tells the browser not to cache pages, Internet Explorer won't deliver that file to the user. Solutions Internet Explorer handles downloads in a rather unusual manner: it makes two requests to the web site. The first request downloads the file and stores it in the cache before making a second request, the response to which is not stored. The second request invokes the process of delivering the file to the end user in accordance with the file's type--for instance, it starts Acrobat Reader if the file is a PDF document. Therefore, if you send the cache headers that instruct the browser not to cache the page, Internet Explorer will delete the file between the first and second requests, with the unfortunate result that the end user receives nothing! If the file you're serving through the PHP script won't change, one solution to this problem is simply to disable the "don't cache" headers, pragma and cache-control, which we discussed in "How do I prevent web browsers from caching a page?", for the download script. If the file download will change regularly, and you want the browser to download an up-to-date version of it, you'll need to use the Last-Modified header that we met in "How do I control client-side caching?", and ensure that the time of modification remains the same across the two consecutive requests. You should be able to achieve this goal without affecting users of browsers that handle downloads correctly. One final solution is to write the file to the file system of your web server and simply provide a link to it, leaving it to the web server to report the cache headers for you. Of course, this may not be a viable option if the file is supposed to be secured.
    How do I use output buffering for server-side caching?
    Server-side processing delay is one of the biggest bugbears of dynamic web pages. We can reduce server-side delay by caching output. The page is generated normally, performing database queries and so on with PHP; however, before sending it to the browser, we capture and store the finished page somewhere--in a file, for instance. The next time the page is requested, the PHP script first checks to see whether a cached version of the page exists. If it does, the script sends the cached version straight to the browser, avoiding the delay involved in rebuilding the page. Solution Here, we'll look at PHP's in-built caching mechanism, the output buffer, which can be used with whatever page rendering system you prefer (templates or no templates). Consider situations in which your script displays results using, for example, echo or print, rather than sending the data directly to the browser. In such cases, you can use PHP's output control functions to store the data in an in-memory buffer, which your PHP script has both access to and control over. Here's a simple example that demonstrates how the output buffer works: buffer.php (excerpt) <?php ob_start(); echo '1. Place this in the buffer<br />'; $buffer = ob_get_contents(); ob_end_clean(); echo '2. A normal echo<br />'; echo $buffer; ?> The buffer itself stores the output as a string. So, in the above script, we commence buffering with the ob_startfunction, and use echo to display a piece of text which is stored in the output buffer automatically. We then use the ob_get_contents function to fetch the data the echo statement placed in the buffer, and store it in the $buffer variable. The ob_end_clean function stops the output buffer and empties the contents; the alternative approach is to use the ob_end_flushfunction, which displays the contents of the buffer. The above script displays the following output: 2. A normal echo 1. Place this in the buffer In other words, we captured the output of the first echo, then sent it to the browser after the second echo. As this simple example suggests, output buffering can be a very powerful tool when it comes to building your site; it provides a solution for caching, as we'll see in a moment, and is also an excellent way to hide errors from your site's visitors, as is discussed in Chapter 9. Output buffering even provides a possible alternative to browser redirection in situations such as user authentication. In order to improve the performance of our site, we can store the output buffer contents in a file. We can then call on this file for the next request, rather than having to rebuild the output from scratch again. Let's look at a quick example of this technique. First, our example script checks for the presence of a cache file: sscache.php (excerpt) <?php if (file_exists('./cache/page.cache')) { readfile('./cache/page.cache'); exit(); } If the script finds the cache file, we simply output its contents and we're done! If the cache file is not found, we proceed to output the page using the output buffer: sscache.php (excerpt) ob_start(); ?> <!DOCTYPE html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Cached Page</title> </head> <body> This page was cached with PHP's <a href="http://www.php.net/outcontrol" >Output Control Functions</a> </body> </html> <?php $buffer = ob_get_contents(); ob_end_flush(); Before we flush the output buffer to display our page, we make sure to store the buffer contents in the $buffer variable. The final step is to store the saved buffer contents in a text file: sscache.php (excerpt) $fp = fopen('./cache/page.cache','w'); fwrite($fp,$buffer); fclose($fp); ?> The page.cache file contents are exactly same as the HTML that was rendered by the script: cache/page.cache (excerpt) <!DOCTYPE html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Cached Page</title> </head> <body> This page was cached with PHP's <a href="http://www.php.net/outcontrol" >Output Control Functions</a> </body> </html> Discussion For an example that shows how to use PHP's output buffering capabilities to handle errors more elegantly, have a look at the PHP Freaks article Introduction to Output Buffering, by Derek Ford. What About Template Caching? Template engines often include template caching features--Smarty is a case in point. Usually, these engines offer a built-in mechanism for storing a compiled version of a template (that is, the native PHP generated from the template), which prevents us developers from having to recompile the template every time a page is requested. This process should not be confused with output--or content--caching, which refers to the caching of the rendered HTML (or other output) that PHP sends to the browser. In addition to the content cache mechanisms discussed in this chapter, Smarty can cache the contents of the HTML page. Whether you use Smarty's content cache or one of the alternatives discussed in this chapter, you can successfully use both template and content caching together on the same site. HTTP Headers and Output Buffering Output buffering can help solve the most common problem associated with the header function, not to mention the issues surrounding session_start and set_cookie. Normally, if you call any of these functions after page output has begun, you'll get a nasty error message. When output buffering's turned on, the only output types that can escape the buffer are HTTP headers. If you use ob_start at the very beginning of your application's execution, you can send headers at whichever point you like, without encountering the usual errors. You can then write out the buffered page content all at once, when you're sure that no more HTTP headers are required. Use Output Buffering Responsibly While output buffering can helpfully solve all our header problems, it should not be used solely for that reason. By ensuring that all output is generated after all the headers are sent, you'll save the time and resource overheads involved in using output buffers.
    How do I cache just the parts of a page that change infrequently?
    Caching an entire page is a simplistic approach to output buffering. While it's easy to implement, that approach negates the real benefits presented by PHP's output control functions to improve your site's performance in a manner that's relevant to the varying lifetimes of your content. No doubt, some parts of the page that you send to visitors will change very rarely, such as the page's header, menus, and footer. But other parts--for example, the list of comments on your blog posts--may change quite often. Fortunately, PHP allows you to cache sections of the page separately. Solution Output buffering can be used to cache sections of a page in separate files. The page can then be rebuilt for output from these files. This technique eliminates the need to repeat database queries, while loops, and so on. You might consider assigning each block of the page an expiry date after which the cache file is recreated; alternatively, you may build into your application a mechanism that deletes the cache file every time the content it stores is changed. Let's work through an example that demonstrates the principle. Firstly, we'll create two helper functions, writeCache and readCache. Here's the writeCache function: smartcache.php (excerpt) <?php function writeCache($content, $filename) { $fp = fopen('./cache/' . $filename, 'w'); fwrite($fp, $content); fclose($fp); } The writeCache function is quite simple; it just writes the content of the first argument to a file with the name specified in the second argument, and saves that file to a location in the cache directory. We'll use this function to write our HTML to the cache files. The readCache function will return the contents of the cache file specified in the first argument if it has not expired--that is, the file's last modified time is not older than the current time minus the number of seconds specified in the second argument. If it has expired or the file does not exist, the function returns false: smartcache.php (excerpt) function readCache($filename, $expiry) { if (file_exists('./cache/' . $filename)) { if ((time() - $expiry) > filemtime('./cache/' . $filename)) { return false; } $cache = file('./cache/' . $filename); return implode('', $cache); } return false; } For the purposes of demonstrating this concept, I've used a procedural approach. However, I wouldn't recommend doing this in practice, as it will result in very messy code and is likely to cause issues with file locking. For example, what happens when someone accesses the cache at the exact moment it's being updated? Better solutions will be explained later on in the chapter. Let's continue this example. After the output buffer is started, processing begins. First, the script calls readCache to see whether the file header.cache exists; this contains the top of the page--the HTML <head> tag and the start <body> tag. We've used PHP's date function to display the time at which the page was actually rendered, so you'll be able to see the different cache files at work when the page is displayed: smartcache.php (excerpt) ob_start(); if (!$header = readCache('header.cache', 604800)) { ?> <!DOCTYPE html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Chunked Cached Page</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> </head> <body> <p>The header time is now: <?php echo date('H:i:s'); ?></p> <?php $header = ob_get_contents(); ob_clean(); writeCache($header,'header.cache'); } Note what happens when a cache file isn't found: the header content is output and assigned to a variable, $header, with ob_get_contents, after which the ob_clean function is called to empty the buffer. This allows us to capture the output in "chunks" and assign them to individual cache files with the writeCache function. The header of the page is now stored as a file, which can be reused without our needing to rerender the page. Look back to the start of the if condition for a moment. When we called readCache, we gave it an expiry time of 604800 seconds (one week); readCache uses the file modification time of the cache file to determine whether the cache is still valid. For the body of the page, we'll use the same process as before. However, this time, when we call readCache, we'll use an expiry time of five seconds; the cache file will be updated whenever it's more than five seconds old: smartcache.php (excerpt) if (!$body = readCache('body.cache', 5)) { echo 'The body time is now: ' . date('H:i:s') . '<br />'; $body = ob_get_contents(); ob_clean(); writeCache($body, 'body.cache'); } The page footer is effectively the same as the header. After the footer, the output buffering is stopped and the contents of the three variables that hold the page data are displayed: smartcache.php (excerpt) if (!$footer = readCache('footer.cache', 604800)) { ?> <p>The footer time is now: <?php echo date('H:i:s'); ?></p> </body> </html> <?php $footer = ob_get_contents(); ob_clean(); writeCache($footer, 'footer.cache'); } ob_end_clean(); echo $header . $body . $footer; ?> The end result looks like this: The header time is now: 17:10:42 The body time is now: 18:07:40 The footer time is now: 17:10:42 The header and footer are updated on a weekly basis, while the body is updated whenever it is more than five seconds old. If you keep refreshing the page, you'll see the body time updating. Discussion Note that if you have a page that builds content dynamically, based on a number of variables, you'll need to make adjustments to the way you handle your cache files. For example, you might have an online shopping catalog whose listing pages are defined by a URL such as: http://example.com/catalogue/view.php?category=1&page=2 This URL should show page two of all items in category one; let's say this is the category for socks. But if we were to use the caching code above, the results of the first page of the first category we looked at would be cached, and shown for any request for any other page or category, until the cache expiry time elapsed. This would certainly confuse the next visitor who wanted to browse the category for shoes--that person would see the cached content for socks! To avoid this issue, you'll need to incorporate the category ID and page number in to the cache file name like so: $cache_filename = 'catalogue_' . $category_id . '_' . $page . '.cache'; if (!$catalogue = readCache($cache_filename, 604800)) { ...display the category HTML... } This way, the correct cached content can be retrieved for every request. Nesting Buffers You can nest one buffer within another practically ad infinitum simply by calling ob_startmore than once. This can be useful if you have multiple operations that use the output buffer, such as one that catches the PHP error messages, and another that deals with caching. Care needs to be taken to make sure that ob_end_flush or ob_end_clean is called every time ob_start is used.
    How do I use PEAR::Cache_Lite for server-side caching?
    The previous solution explored the ideas behind output buffering using the PHP ob_* functions. Although we mentioned at the time, that approach probably isn't the best way to meet to dual goals of keeping your code maintainable and having a reliable caching mechanism. It's time to see how we can put a caching system into action in a manner that will be reliable and easy to maintain. Solution
    In the interests of keeping your code maintainable and having a reliable caching mechanism, it's a good idea to delegate the responsibility of caching logic to classes you trust. In this case, we'll use a little help from PEAR::Cache_Lite (version 1.7.2 is used in the examples here). Cache_Lite provides a solid yet easy-to-use library for caching, and handles issues such as: file locking; creating, checking for, and deleting cache files; controlling the output buffer; and directly caching the results from function and class method calls. More to the point, Cache_Lite should be relatively easy to apply to an existing application, requiring only minor code modifications. Cache_Lite has four main classes. First is the base class, Cache_Lite, which deals purely with creating and fetching cache files, but makes no use of output buffering. This class can be used alone for caching operations in which you have no need for output buffering, such as storing the contents of a template you've parsed with PHP. The examples here will not use Cache_Lite directly, but will instead focus on the three subclasses. Cache_Lite_Function can be used to call a function or class method and cache the result, which might prove useful for storing a MySQL query result set, for example. The Cache_Lite_Output class uses PHP's output control functions to catch the output generated by your script and store it in cache files; it allows you to perform tasks such as those we completed in "How do I cache just the parts of a page that change infrequently?". The Cache_Lite_File class bases cache expiry on the timestamp of a master file, with any cache file being deemed to have expired if it is older than the timestamp. Let's work through an example that shows how you might use Cache_Lite to create a simple caching solution. When we're instantiating any child classes of Cache_Lite, we must first provide an array of options that determine the behavior of Cache_Lite itself. We'll look at these options in detail in a moment. Note that the cacheDir directory we specify must be one to which the script has read and write access: cachelite.php (excerpt) <?php require_once 'Cache/Lite/Output.php'; $options = array( 'cacheDir' => './cache/', 'writeControl' => 'true', 'readControl' => 'true', 'fileNameProtection' => false, 'readControlType' => 'md5' ); $cache = new Cache_Lite_Output($options); For each chunk of content that we want to cache, we need to set a lifetime (in seconds) for which the cache should live before it's refreshed. Next, we use the start method, available only in the Cache_Lite_Output class, to turn on output buffering. The two arguments passed to the start method are an identifying value for this particular cache file, and a cache group. The group is an identifier that allows a collection of cache files to be acted upon; it's possible to delete all cache files in a given group, for example (more on this in a moment). The start method will check to see if a valid cache file is available and, if so, it will begin outputting the cache contents. If a cache file is not available, start will return false and begin caching the following output. Once the output for this chunk has finished, we use the end method to stop buffering and store the content as a file: cachelite.php (excerpt) $cache->setLifeTime(604800); if (!$cache->start('header', 'Static')) { ?> <!DOCTYPE html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>PEAR::Cache_Lite example</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> </head> <body> <h2>PEAR::Cache_Lite example</h2> <p>The header time is now: <?php echo date('H:i:s'); ?></p> <?php $cache->end(); } To cache the body and footer, we follow the same procedure we used for the header. Note that, again, we specify a five-second lifetime when caching the body: cachelite.php (excerpt) $cache->setLifeTime(5); if (!$cache->start('body', 'Dynamic')) { echo 'The body time is now: ' . date('H:i:s') . '<br />'; $cache->end(); } $cache->setLifeTime(604800); if (!$cache->start('footer', 'Static')) { ?> <p>The footer time is now: <?php echo date('H:i:s'); ?></p> </body> </html> <?php $cache->end(); } ?> On viewing the page, Cache_Lite creates cache files in the cache directory. Because we've set the fileNameProtection option to false, Cache_Lite creates the files with these names: - ./cache/cache_Static_header - ./cache/cache_Dynamic_body - ./cache/cache_Static_footer You can read about the fileNameProtection option--and many more--in "What configuration options does Cache_Lite support?". When the same page is requested later, the code above will use the cached file if it is valid and has not expired. Protect your Cache Files Make sure that the directory in which you place the cache files is not publicly available, or you may be offering your site's visitors access to more than you realize.
    What configuration options does Cache_Lite support?
    When instantiating Cache_Lite (or any of its subclasses, such as Cache_Lite_Output), you can use any of a number of approaches to controlling its behavior. These options should be placed in an array and passed to the constructor as shown below (and in the previous section): $options = array( 'cacheDir' => './cache/', 'writeControl' => true, 'readControl' => true, 'fileNameProtection' => false, 'readControlType' => 'md5' ); $cache = new Cache_Lite_Output($options); Solution The options available in the current version of Cache_Lite (1.7.2) are: cacheDir This is the directory in which the cache files will be placed. It defaults to /tmp/. caching This option switches on and off the caching behavior of Cache_Lite. If you have numerous Cache_Lite calls in your code and want to disable the cache for debugging, for example, this option will be important. The default value is true (caching enabled). lifeTime This option represents the default lifetime (in seconds) of cache files. It can be changed using the setLifeTime method. The default value is 3600 (one hour), and if it's set to null, the cache files will never expire. fileNameProtection With this option activated, Cache_Lite uses an MD5 encryption hash to generate the filename for the cache file. This option protects you from error when you try to use IDs or group names containing characters that aren't valid for filenames; fileNameProtection must be turned on when you use Cache_Lite_Function. The default is true (enabled). fileLocking This option is used to switch the file locking mechanisms on and off. The default is true (enabled). writeControl This option checks that a cache file has been written correctly immediately after it has been created, and throws a PEAR::Error if it finds a problem. Obviously, this facility would allow your code to attempt to rewrite a cache file that was created incorrectly, but it comes at a cost in terms of performance. The default value is true (enabled). readControl This option checks any cache files that are being read to ensure they're not corrupt. Cache_Lite is able to place inside the file a value, such as the string length of the file, which can be used to confirm that the cache file isn't corrupt. There are three alternative mechanisms for checking that a file is valid, and they're specified using the readControlType option. These mechanisms come at the cost of performance, but should help to guarantee that your visitors aren't seeing scrambled pages. The default value is true (enabled). readControlType This option lets you specify the type of read control mechanism you want to use. The available mechanisms are a cyclic redundancy check (crc32, the default value) using PHP's crc32 function, an MD5 hash using PHP's md5 function (md5), or a simple and fast string length check (strlen). Note that this mechanism is not intended to provide security from people tampering with your cache files; it's just a way to spot corrupt files. pearErrorMode This option tells Cache_Lite how it should return PEAR errors to the calling script. The default is CACHE_LITE_ERROR_RETURN, which means Cache_Lite will return a PEAR::Error object. memoryCaching With memory caching enabled, every time a file is written to the cache, it is stored in an array in Cache_Lite. The saveMemoryCachingState and getMemoryCachingState methods can be used to store and access the memory cache data between requests. The advantage of this facility is that the complete set of cache files can be stored in a single file, reducing the number of disk read/write operations by reconstructing the cache files straight into an array to which your code has access. The memoryCaching option may be worth further investigation if you run a large site. The default value is false (disabled). onlyMemoryCaching If this option is enabled, only the memory caching mechanism will be used. The default value is false (disabled). memoryCachingLimit This option places a limit on the number of cache files that will be stored in the memory caching array. The more cache files you have, the more memory will be used up by memory caching, so it may be a good idea to enforce a limit that prevents your server from having to work too hard. Of course, this option places no restriction on the size of each cache file, so just one or two massive files may cause a problem. The default value is 1000. automaticSerialization If enabled, this option will automatically serialize all data types. While this approach will slow down the caching system, it is useful for caching nonscalar data types such as objects and arrays. For higher performance, you might consider serializing nonscalar data types yourself. The default value is false (disabled). automaticCleaningFactor This option will automatically clean old cache entries--on average, one in x cache writes, where x is the value set for this option. Therefore, setting this value to 0 will indicate no automatic cleaning, and a value of 1will cause cache clearing on every cache write. A value of 20 to 200 is the recommended starting point if you wish to enable this facility; it causes cache cleaning to happen, on average, 0.5% to 5% of the time. The default value is 0 (disabled). hashedDirectoryLevel When set to a nonzero value, this option will enable a hashed directory structure. A hashed directory structure will improve the performance of sites that have thousands of cache files. If you choose to use hashed directories, start by setting this value to 1, and increasing it as you test for performance improvements. The default value is 0 (disabled). errorHandlingAPIBreak This option was added to enable backwards compatibility with code that uses the old API. When the old API was run in CACHE_LITE_ERROR_RETURN mode (see the pearErrorMode option earlier in this list), some functions would return a Boolean value to indicate success, rather than returning a PEAR_Error object. By setting this value to true, the PEAR_Error object will be returned instead. The default value is false (disable).
    How do I purge the Cache_Lite cache?
    The built-in lifetime mechanism for Cache_Lite cache files provides a good foundation for keeping your cache files up to date, but there will be some circumstances in which you need the files to be updated immediately. Solution In cases in which you need immediate updates, the methods remove and clean come in handy. The remove method is designed to delete a specific cache file; it takes as arguments the cache ID and group name of the file. To delete the page body cache file we created in "How do I use PEAR::Cache_Lite for server-side caching?", we'd use this code: $cache->remove('body', 'Dynamic'); If we use the clean method, we can delete all the files in our cache directory simply by calling the method with no arguments; alternatively, we can specify a group of cache files to delete. If we wanted to delete both the header and footer cache files we created in "How do I use PEAR::Cache_Lite for server-side caching?", we could do so like this: $cache->clean('Static'); Discussion The remove and clean methods should obviously be called in response to events that arise within an application. For example, if you have a discussion forum application, you probably want to remove the relevant cache files when a visitor posts a new message. Although it may seem like this solution entails a lot of code modifications, with some care it can be applied to your application in a global manner. If you have a central script that's included in every page, your script can simply watch for incoming events--for example, a variable like $_GET['newPost']--and respond by deleting the required cache files. This keeps the cache file removal mechanism central and easier to maintain. You might also consider using the php.ini setting auto_prepend_file to include this code in every PHP script.
    How do I cache function calls?
    Many web sites provide access to their data via web services such as SOAP and XML-RPC. (You can read all about web services in Chapter 12.) As web services are accessed over a network, it's often a very good idea to cache results so that they can be fetched locally, rather than repeating the same slow request to the server multiple times. A simple approach might be to use PHP sessions, but as that solution operates on a per-visitor basis, the opening requests for each visitor will still be slow. Solution Let's assume you wish to create a web page that lists all the SitePoint books available on Amazon. The actual list is not likely to change from moment to moment, so why would we make the request to the Amazon web service every time the web page is displayed? We won't! Instead, we can take advantage of Cache_Lite by caching the results of the XML-RPC request. Requires PEAR::SOAP Version 0.11.0 The following solution uses the PEAR::SOAP library version 0.11.0 to access the Amazon web service. You can find this package on the PEAR web site. Here's some hypothetical code that fetches the data from the remote Amazon server: $results = $amazonClient->ManufacturerSearchRequest($params); Using Cache_Lite_Function, we can cache the results so the data returned from the service can be reused; this will avoid unnecessary network calls and significantly improve performance. The following example code focuses on the caching aspect to prevent us from getting bogged down in the details of using the Amazon web service. You can see the complete script if you download this book's code archive from the SitePoint web site. The Cache_Lite_Function requires the inclusion of the following file: cachefunction.php (excerpt) require_once 'Cache/Lite/Function.php'; We instantiate the Cache_Lite_Function class with some options: cachefunction.php (excerpt) $options = array( 'cacheDir' => './cache/', 'fileNameProtection' => true, 'writeControl' => true, 'readControl' => true, 'readControlType' => 'strlen', 'defaultGroup' => 'SOAP' ); $cache = new Cache_Lite_Function($options); It's important that the fileNameProtection option is set to true (this is in fact the default value, but in this case I've set it manually to emphasize the point). If it were set to false, the filename would be invalid, so the data will not be cached. Here's how we make the calls to our SOAP client class: cachefunction.php (excerpt) $results = $cache->call('amazonClient->ManufacturerSearchRequest', $params); If the request is being made for the first time, Cache_Lite_Function will store the results as a serialized array or object in a cache file (not that you need to worry about this), and this file will be used for future requests until it expires. The setLifeTime method can again be used to specify how long the cache files should survive before they're refreshed; currently, the default value of 3600 seconds (one hour) is being used. You can then use the $results variable exactly as if you were calling the web service method directly. The output of our example script can be seen in Figure 11.1. SitePoint books at Amazon
    Summary
    Caching is an important and often overlooked aspect of web site development. Many factors that affect the performance of today's web sites weren't a problem for their predecessors--from complex, dynamic page generation, to a reliance on third-party data over the network. In this chapter, we've examined HTML meta tags, HTTP headers, PHP output buffering and PEAR::Cache_Lite, and we've seen how you can use them to control the caching of your web site content and improve the site's reliability and performance. Implementing a caching system for your site might be simple, but ultimately, it depends on your requirements. If you have a busy and predominantly static web site--such as a blog--that's managed through a content management system, it will likely require little alteration, yet may benefit from huge performance improvements resulting from a small investment of your time. Setting up caching for a more complex site that generates content on a per-user basis, such as a portal or shopping cart system, will prove a little more tricky and time consuming, but the benefits are still clear. Regardless, I hope the information in this chapter has given you a good grasp of the options available, and will help you determine which techniques are most suitable for your application. Don't forget to download this chapter, plus two others -- PDO and Databases, and Access Control -- to enjoy offline. For information on the contents of the book's other chapters, check out the full Table of Contents.

  • PHP 缓存,加速,优化程序(eAccelerator,apc,xcache) -加快magento运行速度

    9 year(s) ago

    上次在magento官方论坛遇到一个国内同行,在他们一个主机性能帖子里面我说了两个建议:
    
    1 使用缓存
    
    2 改进zend框架.
    
    没想到这个被他们大为嘲笑...唉...如果大家做开源的可以有一个良好的社区氛围就好了.
    
    实际情况是magento在有缓存加速的情况下提高的性能是成倍的.如果代码调整到位,充分利用了缓冲op-code的性能提升,那么magento的运行速度是比较满意的.
    
    目前在php  op-code的缓存方案里面,一共有好几个可选项. apc,eAccelerator以及xcache
    
    这三个目前我们评测下来都比较不错的.
    
    apc由于目前我们还没有找到和zend optimizer和平共处的方案,所以大家安装的时候需要先考虑清楚.
    
    eAccelerator是可以和zend optimizer一起使用的.
    
    xcache的panel是很不错的,提供的缓存控制信息非常充分,让人眼前一亮.
    
    具体测试三者区别,我们打算将来分别在相同环境里面再做具体分析.目前脱离应用跑hello world是无意义的.
    
    eAccelerator 地址: http://eaccelerator.net/  The latest release, 0.9.5.3, supports PHP 4 and all PHP 5 releases including 5.2
    
    APC 地址:http://pecl.php.net/package/APC
    
    3.1.3p1 beta 2009-08-14 APC-3.1.3p1.tgz (138.9kB) [Changelog]
    xcache 地址: http://xcache.lighttpd.net/ 最新版本:http://xcache.lighttpd.net/wiki/Release-1.3.0 PHP 5.3 支持 大家在选择的时候根据自身系统,编译环境的情况,以及熟悉程度来使用对应方案.详细的三个评测我们会在以后做出. 以供大家参考

  • FLOW3 一个支持面向方面编程(AOP)的模型驱动编程(Model Driven Development)的PHP框架

    9 year(s) ago

    FLOW3 一个支持面向方面编程(AOP)的模型驱动编程(Model Driven Development)的PHP框架
    
    一个框架的好坏不完全看性能的高低,不然OOP的诞生就没有意义了.
    
    FLOW3这个框架与目前流行的各家框架的对比如下:
    
    fully supported planned (for the near future) not fully supported - not supported or unknown
    Project FLOW3 Zend Framework eZ Components Symfony cakePHP Ruby on Rails SpringSource Agavi
    Organisation TYPO3 Association Zend Technologies Ltd eZ Systems sensiolabs Cake Development Corporation 37 signals SpringSource Bitextender
    Language PHP PHP PHP PHP PHP Ruby Java PHP
    Modular Packages yes yes yes yes partly yes yes yes
    Package Repository planned - partly - - yes yes yes
    Skeletons / Scaffolding planned yes - yes yes yes yes yes
    MVC yes yes planned yes yes yes yes yes
    MVC w/ AJAX support planned yes - yes yes yes yes -
    DDD Optimized Layer Architecture yes - - - - - partly -
    AOP yes - - - - - yes -
    Dependency Injection yes - - - - - yes -
    Object Lifecycle Management yes partly - - partly partly yes -
    Persistence (Active Record) - partly yes yes - yes yes -
    Persistence (Domain Model) yes - - - - yes -
    JSR-283 Content Repository yes - - - - - yes -
    Testing Framework yes yes yes yes yes yes yes yes
    Developed using Continuous Integration yes partly yes - - yes yes -
    i18n & l10n planned yes yes yes - yes yes yes
    Security Framework planned partly - partly - yes yes partly
    Template Framework yes - yes yes yes yes yes partly
    Caching Framework yes yes yes yes yes yes yes yes
    Object Validation Framework yes yes partly yes yes yes yes yes
    License LGPL New BSD License New BSD License MIT License MIT License MIT / Ruby License Apache License LGPL
    Version we looked at 1.0.0-alpha5 1.8 2008.1 1.1 1.2 2.1 2.5.6 1.0β
    上图不难看出,FLOW3这个框架很有发展前途! 下载地址:http://flow3.typo3.org/download/ 最新版本 FLOW3 1.0.0-alpha5.tgz 官方给出的特色罗列
    • The Object Manager is in charge of building, caching and combining objects. It is a lightweight Inversion-of-Control container with first-class support for Dependency Injection.
    • The AOP Framework enables you to use the powerful techniques of Aspect Oriented Programming.
    • The MVC Framework takes care of requests and responses and provides you with a powerful, easy-to use Model-View-Controller implementation.
    • The Persistence Framework realizes a unique transparent persistence layer based on the principles of Domain-Driven Design, backed by our JSR-283 based content repository.
    • The Validation module provides a validation and filtering framework with built-in rules as well as support for custom validation of any object.
    • The Property module implements the concept of property editors and is used for setting and retrieving object properties.
    • The Package Manager allows you to download, install, configure and uninstall packages and share new features with the FLOW3 community.
    • The Resource Manager contains functions for providing, caching, securing and retrieving resources.
    • The Signal Slot sub package provides an annotation based event system based on the Signal Slot design pattern.
    • The Error module handles errors and exceptions and provides utility classes for this purpose.
    • The Reflection API complements PHP's built-in reflection support by advanced annotation handling and metadata caching for speed.
    • The Security Framework provides "touchless" security by enforcing security policies through AOP.

    What's in the Package

    The FLOW3 package is composed of modules, each of them playing their own important part in the framework:

    • The Object Manager is in charge of building, caching and combining objects. It is a lightweight Inversion-of-Control container with first-class support for Dependency Injection.
    • The AOP Framework enables you to use the powerful techniques of Aspect Oriented Programming.
    • The MVC Framework takes care of requests and responses and provides you with a powerful, easy-to use Model-View-Controller implementation.
    • The Persistence Framework realizes a unique transparent persistence layer based on the principles of Domain-Driven Design, backed by our JSR-283 based content repository.
    • The Validation module provides a validation and filtering framework with built-in rules as well as support for custom validation of any object.
    • The Property module implements the concept of property editors and is used for setting and retrieving object properties.
    • The Package Manager allows you to download, install, configure and uninstall packages and share new features with the FLOW3 community.
    • The Resource Manager contains functions for providing, caching, securing and retrieving resources.
    • The Signal Slot sub package provides an annotation based event system based on the Signal Slot design pattern.
    • The Error module handles errors and exceptions and provides utility classes for this purpose.
    • The Reflection API complements PHP's built-in reflection support by advanced annotation handling and metadata caching for speed.
    • The Security Framework provides "touchless" security by enforcing security policies through AOP.
    ... and much more

  • Joomla 1.6 alpha2 发布,新的功能!

    9 year(s) ago

    Joomla 1.6 alpha2 发布了,新的版本包括很多新功能,包括权限控制库,可扩展用户数据域,去表格的content布局(tabless),改进的内容模块(com_content),新的前台,后台模板.
    
    最关键的是,目前mootools 支持1.2 ,性能上面由于基于对php5.2的支持,现在性能大大高于1.5
    
    
    
    The Joomla project is pleased to announce the immediate release of Joomla 1.6 alpha 2. This release contains many new features requested by the community; most notably, ACL. Other features are listed below as well as what you can expect in the future for Joomla 1.6.
    
    This is an alpha release. It is intended to be a developer/hobbyist preview and is not intended to be used on a production web site.
    
    New improvements/features since alpha 1 include:
    
    • ACL: access management for global permissions as well as content item specific permissions, variable usergroups, users member of more than one usergroup, permissions are inherited, really fast
    • Extendable user profile, profile view in frontend, extendable user parameters
    • Tableless com_content layouts
    • Improved com_content modules (mod_articles_archive, mod_articles_latest, mod_articles_popular)
    • Article linker plugin for editors
    • New frontend template (atomic)
    • New backend template (bluestork)
    • New uploader for media manager
    Other Joomla 1.6 improvements that existed in alpha 1:
    • Mootools 1.2
    • Refactored backend
    • JForm
    • Nested Categories and category parameters
    • New views in frontend: categories, category
    • Lots of small code improvements, almost cut the code size in half while adding to the functionality
    • PHP 5.2 required, huge performance improvements, partially eaten up by new features => 1.6 will be faster than 1.5
    What's next? After alpha 2, the Joomla community can expect a beta release. There are no intentions for a 3rd alpha release. You can also expect to see the following future improvements:
    • Commenting solution is going to be added
    • Additional DB drivers
    • Lots of small performance/UI/code improvements
    We would like to thank all those involved who helped make this release possible. Download here: http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&frs_package_id=3585 Discuss here: http://forum.joomla.org/viewtopic.php?f=9&t=454211

  • Magento Javascript(Prototype)优化尺寸

    9 year(s) ago

    目前我们优化的magento Javascript有了大幅减少,未启用gzip的情况下
    
    优化前尺寸为:283 KB-300多KB
    
    优化后尺寸为:180KB左右
    
    如需要进一步优化尺寸需要使用jquery来重构js代码.
    

  • 大流量下在线视频流系统需要考虑的P2P分流作用

    9 year(s) ago

    目前BitTorrent是广为大家所接受的下载方式之一.
    
    他们最新的DNA技术通过P2P改进的形式(服务器作为种子,其他客户端互相支持保证尽可能不断流) ,流程范例如下:
    
    1 发布资源,做成适合的分布式数据.
    
    
    
    2 发布客户端下载(这点是最大欠缺,需要客户端嵌入浏览器):
    
    
    
    3 进行点对点下载(服务器辅助)
    
    
    
    根据数据显示有一半左右甚至更高的流量将会被用户之间传送.
    
    这个方案适合大型视频网站,而且有很强的公信力来要求客户安装客户端.
    
    目前我们将其作为一个方案提供给国内一家日访问量极大的客户进行实施.
    

  • Alipay(支付宝) Magento Payment Gateway(Open Source)

    9 year(s) ago

    我们提供免费的支付宝支付接口,请大家在magento connetct 下载,或者通过git 获取
    
    Magento Connect
    
    git
    
    如果您觉得本模块,帮助了您,请支持我们!
    
    
    
    If you like this module,please support us to continue open source! Alipay(支付宝) : www.alipay.com CosmoCommerce: www.cosmocommerce.com OpenSource Support Information: Email:opensource@cosmocommerce.com Tel: +86-021-66346672 Cosmo Mao Welcome your feedback, thanks!

  • 99Bill(快钱) Magento Payment Gateway(Open Source)

    9 year(s) ago

    我们提供免费的快钱支付接口,请大家在magento connetct 下载,或者通过git 获取
    
    Magento Connect
    
    git
    
    如果您觉得本模块,帮助了您,请支持我们!
    
    
    
    If you like this module,please support us to continue open source! 99BIll(快钱) : www.99bill.com CosmoCommerce: www.cosmocommerce.com OpenSource Support Information: Email:opensource@cosmocommerce.com Tel: +86-021-66346672 Cosmo Mao Welcome your feedback, thanks!

  • AddThis API 社会收藏接口整合

    9 year(s) ago

    AddThis是目前比较流行的一个收藏分享网站.
    
    通过定制,我们可以支持界面自我控制,数据分析和流程再造.
    
    AddThis 提供的Web Service: http://www.addthis.com/help/web-service-features
    
    AddThis 分析接口: http://www.addthis.com/help/analytics-api
    
    以下信息来自AddThis Menu API文档,用于定制菜单:
    
    
    

    Overview

    After gathering your feedback for a year or so, we've completely redesigned our API, with the following goals in mind:
    • If you're not a JavaScript wizard, the most common customizations should still be easy
    • In fact, most use cases should be covered with as little JavaScript as possible
    • But even the most complicated configurations should be possible somehow (for example, multiple buttons on a page behaving differently)
    • UI management code in JavaScript shouldn't be required to actually use the tools
    The new API supports global configuration (as with our original API) as well as per-element configuration--every button on a page can behave differently in almost every regard. You might not need to ever go that far. But you could. The new API also offers a few new ways of rendering buttons. In the past, we distributed code with inline JavaScript. Not only did this lock us in to whatever code we distributed, but often we found users had trouble managing that much code, or even just pasting inline JavaScript into their CMSs. Now we take care of all that for you. You tell us which elements you want to be AddThis buttons (and how you'd like them configured), and we take care of the rest. Why? We're big fans of modern JavaScript toolkits like jQuery that separate markup and interactive behavior like this. (If you're not familiar with the concept of Unobtrusive JavaScript, here's a few articles.) It's easier for everyone to manage, and, because it lets us drastically simplify the code we distribute, should even improve load times.

    An Illustrative Comparison

    API 1.0

    <a href="http://www.addthis.com/bookmark.php?v=20" 
     onmouseover="return 
    addthis_open(this, '', '[URL]', '[TITLE]');" 
     onmouseout="addthis_close();" 
     onclick="return addthis_sendto();"><img src=
    "http://s7.addthis.com/static/btn/lg-share-en.gif" 
     width="125" height="16" border="0" alt="Share"/></a>

    API 2.0

    <a class="addthis_button"></a>

    Configuration

    We support two types of configuration objects: one for configuring our UI tools, and one for specifying what you're sharing.

    UI Configuration

    The same object format can be used for specifying global or instance configuration. To specify global configuration, the special name addthis_config must be used. For example:
    var addthis_config =
    {
       // ... members go here
    }
    UI Configuration Options
    Name Description Type Default value
    username Your AddThis username. Always global to a page. string none
    services_exclude Services to exclude from all menus. For example, setting this to 'facebook,myspace' would hide Facebook and MySpace on all our menus. Always global. string (csv) none
    services_compact Services to use in the compact menu. For example, setting this to 'print,email,favorites' would result in only those three services appearing. Always global. string (csv) We regularly optimize the default list based on our data.
    services_expanded Services to use in the expanded menu. Useful if very few services are desired -- specifying a long list via services_exclude could be tiresome, and wouldn't catch a new service added later. For example, setting this to 'bebo,misterwong,netvibes' would result in only those three services appearing in the expanded menu. Always global. string (csv) all the services AddThis offers
    services_custom Specify your own AddThis bookmarking service like so: {name: "My Service", url: "http://share.example.com?url={{URL}}&title={{TITLE}}", icon: "http://example.com/icon.jpg"}. All three fields must be present for each custom service. Always global. Sample usage. Analytics will appear in your account under the service's base domain name (no subdomains--"example.com" in this case), and the first service specified will appear in the compact menu. Only one service per domain is accepted. All custom services specified automatically get added to the expanded menu. To include a custom service with services_expanded, refer to it by the service's base domain name as in the analytics console. (In this case, "example.com".) array of custom service objects none
    ui_click If true, the compact menu will never appear upon mousing over the regular button. Instead, it will be revealed upon clicking the button. boolean false
    ui_delay Delay, in milliseconds, before compact menu appears when mousing over a regular button. Capped at 500 ms. integer 0
    ui_hover_direction Normally, we show the compact menu in the direction of the user's browser that has the most space (i.e., a button at the bottom of the page will pop up, and vice versa). You can override this behavior with this setting: 1 to force the menu to appear "up", -1 to force the menu to appear "down". integer 0
    ui_language For forcing the menu to use a particular language, specified via ISO code. For example, setting this to "sv" would show the menu in Swedish. Note: Regardless of the number of times it's specified, only one language is supported per page. string User's browser
    ui_offset_top Number of pixels to offset the top of the compact menu from its parent element integer 0
    ui_offset_left Number of pixels to offset the left of the compact menu from its parent element integer 0
    ui_header_color Color of the compact and extended menus' header foregrounds. For example, "#FFF" would make the text white. hex string n/a
    ui_header_background Color of the compact and extended menus' header backgrounds. For example, "#000" would make the text appear on a black background. hex string n/a
    ui_cobrand Additional branding message to be rendered in the upper-right-hand corner of the menus. Should be less than 15 characters in most cases to render properly. string none
    ui_use_addressbook If true, the user will be able import their contacts from popular webmail services when using AddThis's email sharing. boolean false
    ui_508_compliant If true, clicking the AddThis button will open a new window to a page supporting sharing without JavaScript. boolean false
    data_track_linkback Set to true to allow us to append a variable to your URLs upon sharing. We'll use this to track how many people come back to your content via links shared with AddThis (report coming soon). Highly recommended. Always global. boolean false
    data_ga_tracker Google Analytics tracking object. If set, we'll send AddThis tracking events to Google, so you can have integrated reporting. Sample usage. object null
    data_use_flash If not true, the AddThis button won't load our Flash-based analytics engine. Some future reports will be affected. Always global. boolean true
    data_use_cookies If not true, we won't set any cookies at all. Some future reports will be affected. Always global. boolean true
    Supported Services
    For use in service_* configuration options.
    code description
    a1webmarks A1-Webmarks, a social bookmarking tool
    aim AIM, the ubiquitous instant messaing platform
    amazonwishlist Amazon.com's Wishlist
    amenme Amen Me!, a social bookmarking site with a Christian slant
    aolmail AOL Mail, AOL's webmail platform
    arto Arto, a picture sharing site
    ask Ask.com
    backflip Backflip, a social bookmarking tool
    baidu Baidu, a social bookmarking tool
    ballhype BallHype, a social sports news aggregator
    bebo Bebo, a social network
    bitly Bit.ly, a URL shortener
    bizsugar bizSugar, a social media aggregator
    bleetbox Bleetbox, a social chat network
    blinklist Blinklist, a social bookmarking tool
    blogger Blogger, a blogging platform
    bloggy Bloggy, a Swedish blogging platform
    blogmarks Blogmarks, a social bookmarking tool
    bobrdobr Bobrdobr, a Russian social bookmarking tool
    bordom Bordom, a link sharing site
    brainify Brainify, a social bookmarking tool for academics and researchers
    bryderi Bryderi.se, a Swedish social shopping platform
    buddymarks BuddyMarks, a social bookmarking tool
    buzz Buzz, a social news aggregator
    buzz_fr Buzz.fr, the French version of Buzz
    care2 Care2, a health-focused social bookmarking tool
    citeulike CiteULike, a social citation tool for academics and researchers
    connotea Connotea, a social bookmarking tool for academics and researchers
    delicious Delicious (Delicious is a social bookmarking service that allows users to tag)
    designmoo Designmoo, a social design news aggregator
    digg Digg, a social news aggregator
    diglog diglog, a Chinese social bookmarking tool
    diigo Diigo, a social bookmarking and annotation tool
    domelhor DoMelhor, a Portuguese social news aggregator
    doower Doower.com
    dosti Dosti, an Indian-language news aggregator
    dotnetkicks DotNetKicks, a social .NET news aggregator
    dzone dzone, a social bookmarking tool for developers
    edelight edelight, a German social shopping platform
    ekudos eKudos, a Dutch social news aggregator
    email The AddThis email interface
    eucliquei euCliquei, a Latin American social news aggregator
    evernote Evernote, a social note-taking tool
    fabulously40 Fabulously40, a social network for women "of age"
    facebook Facebook, a social network
    fark Fark, a social news aggregator
    faves Faves, a social bookmarking tool
    favorites Adds the page to the browser's bookmarks
    favoritus Favoritus, a social bookmarking tool
    fnews Fnews, an Azerbaijani social news aggregator
    folkd Folkd, a social bookmarking tool
    forgetfoo forgetfoo.com
    fresqui Fresqui, a Spanish social news aggregator
    friendfeed FriendFeed, a real-time social feed aggregator
    funp funP, a Taiwanese social bookmarking tool
    gabbr Gabbr, a social news aggregator
    gacetilla Gacetilla, a Spanish social news aggregator
    globalgrind GlobalGrind, a social content aggregator
    gluvsnap GluvSnapPin, a social health news aggregator
    gmail Gmail, Google's email platform
    google Google Bookmarks, a social bookmarking tool
    googlereader Google Reader, a feed reader
    googletranslate Google Translate, a translation service
    gravee Gravee, a social recommendation engine
    grumper Grumper, for complaining about anything
    habergentr Haber.gen.tr, a Turkish social news aggregator
    hackernews Hacker News, a social technology news aggregator
    hadashhot Hadash Hot, an Israeli social news aggregator
    hatena Hatena, a Japanese social bookmarking tool
    hellotxt HelloTxt, a link-sharing tool
    hemidemi HEMiDEMi, a Taiwanese social bookmarking tool
    hipstr hipstr, a social bookmarking tool
    hitmarks Hitmarks, a social bookmarking tool
    hotklix Hotklix, an social entertainment news aggregator
    hotmail Hotmail, Microsoft's webmail platform
    hyves Hyves, a Dutch social network
    jamespot Jamespot, a social sharing platform
    jumptags Jumptags, a social bookmarking tool
    kaboodle Kaboodle, a social shopping platform
    kaevur Kaevur, a link sharing tool
    kirtsy KiRTSY, a social sharing platform
    kudos Kudos, a Norwegian social bookmarking tool
    laaikit Laaikit, a social news aggregator
    librerio Librerio, a social bookmarking tool
    linkagogo Link-a-Gogo, a social bookmarking tool
    linkedin LinkedIn, a social network for business
    live Windows Live Favorites, a social bookmarking tool
    livejournal LiveJournal, a blogging platform
    lunch Lunch.com, a social reviews platform
    lynki Lynki, a social sharing platform
    memori Memori.ru, a Russian social bookmarking tool
    meneame Menéame, a Spanish social content aggregator
    mindbodygreen Mindbodygreen, a health-focused social bookmarking tool
    misterwong Mister Wong, a social bookmarking tool
    misterwong_de Mister Wong.de, the German-language version of Mister Wong
    mixx Mixx, a social news aggregator
    multiply Multiply, a media sharing tool
    myaol myAOL Favorites, a social bookmarking tool
    mynasa My NASA, NASA's bookmarking tool
    mylinkvault MyLinkVault, a social bookmarking tool
    myspace MySpace, a social network
    n4g N4G, a social game news aggregator
    netlog NetLog, a social network
    netvibes Netvibes, a personal news aggregator
    netvouz Netvouz, a social bookmarking tool
    newstrust NewsTrust, a social network for journalists
    newsvine Newsvine, a social news aggregator
    nujij Nujij, a Dutch social bookmarking tool
    oknotizie OKNOtizie, an Italian social news aggregator
    oneview Oneview, a social news aggregator
    oyyla Oyyla, a Turkish social news and media aggregator
    phonefavs PhoneFavs, a mobile-friendly social bookmarking tool
    pingfm Ping.fm, a social bookmarking and micro-blogging tool
    planypus Planypus, a social wiki
    plaxo Plaxo, an online address book and social network
    plurk Plurk, a blogging platform
    polladium Polladium, an online polling system
    posterous Posterous, a blogging platform
    print Print the current page
    printfriendly PrintFriendly, a service for printing online content better
    propeller Propeller, a social news aggregator
    pusha Pusha, a social news aggregator
    reddit Reddit, a social news aggregator
    segnalo Segnalo, an Italian social bookmarking tool
    shetoldme She Told Me, a social news aggregator
    simpy Simpy, a social bookmarking tool
    slashdot Slashdot, a social technology news aggregator
    smaknews Smak News, a social news aggregator for women
    sodahead SodaHead, a social discussion platform
    sonico Sonico, a photo sharing platform
    sphinn Sphinn, a social network for marketers
    squidoo Squidoo, a content aggregator
    startaid Startaid, a social bookmarking tool
    strands Strands, a social network for runners
    studivz studiVZ, a German social network
    stumbleupon StumbleUpon, a social content discovery platform
    stylehive Stylehive, a social network for the stylish
    svejo Svejo, a Bulgarian social news aggregator
    symbaloo Symbaloo, a personal web portal
    tagza Tagza, a social bookmarking tool
    technet Technet, Microsoft's TechNet Library
    technorati Technorati, a blog indexing and tracking tool by tag or keyword. Also provides popularity indexes.)
    tellmypolitician TellMyPolitician, a tool for contacting your local politician
    thisnext ThisNext, a social shopping platform
    tipd Tip'd, a social financial news aggregator
    transferr Transferr, a personal portal
    tulinq Tulinq, a Spanish social news aggregator
    tumblr Tumblr, a blogging platform
    tusul Tusul, a Turkish social news aggregator
    twitter Twitter, a micro-blogging platform
    typepad Typepad, a blogging platform
    viadeo Viadeo, a social networking tool for business
    virb Virb, a social media sharing tool
    webnews Webnews, a German social news aggregator
    wordpress Wordpress, a blogging platform
    worio Worio, a social content discovery engine
    wovre Wovre, a social network
    wykop Wykop, a social news aggregator
    yahoobkm Yahoo! Bookmarks, a social bookmarking tool
    yahoomail Yahoo! Mail, Yahoo's email platform
    yammer Yammer, a micro-blogging platform
    yardbarker Yardbarker, a social sports news aggregator
    yigg Yigg, a German social news aggregator
    youmob YouMob, a social discussion platform

    Sharing Configuration

    The same object format can be used for specifying global or instance configuration. To specify global configuration, the special name addthis_share must be used. For example:
    var addthis_share =
    {
       // ... members go here
    }
    Sharing Configuration Options
    Name Description Type Default value
    url URL to share (tutorial here) url window URL
    title title of shared object (tutorial here) string window title
    content additional HTML content to share with link (tutorial here) string none
    email_template name of template to use for emailed shares (tutorial here) string none
    email_vars associative array mapping custom email variables to values (tutorial here) object none
    templates associative array mapping services to post templates (see below) object none
    Templates Some destinations support more than just posting a link and a link title. Twitter, for example, lets the user post a bunch of arbitrary content. By using a template, you can customize the default post. Sample template:
        twitter: 'check out {{url}} (from @addthis)'
    We'll fill in a few different tokens for you -- you can use all, some or none of them:
    • {{url}} - the URL being shared; on destinations that have a length limit (i.e., Twitter), we'll automatically shorten the URL for you
    • {{lurl}} - the URL being shared; even on destinations that have a length limit, this token (short for "long URL") will never shorten your URL
    • {{title}} - the title being shared
    • {{html}} - the arbitrary HTML shared (the "content" parameter above)
    You can provide one template per destination that supports them (currently just Twitter):
    var addthis_share = 
    { 
    // ...
        templates: {
                       twitter: 'check out {{url}} (from @example_dot_com)',
                   }
    }
    Section 508 Compliance
    You can make your AddThis button Section 508 compliant by using ui_508_compliant.
    <script type="text/javascript">
    var addthis_config =
    {
       ui_508_compliant: true
    }
    </script>
    <a class="addthis_button"></a>

    Rendering with JavaScript

    You can render the AddThis button anywhere on your page using JavaScript. All of our JavaScript rendering functions take the form:
    addthis.function(target(s), [configurationObject], [sharingObject]);
    where target(s) can be
    1. a classname, specified with a dot: '.sharing-button'
    2. an id, specified with a hash: '#addthis_button_1'
    3. an actual HTML element reference
    4. an array of HTML element references
    If configurationObject is unspecified, global defaults (i.e., the addthis_config object) are used. If sharingObject is unspecified, global defaults (i.e., the addthis_share object) are used. At present, we only support rendering of buttons via JavaScript, but we plan to support inline menus as well in the future.

    The Button

    Renders a normal AddThis button at an anchor tag. If the tag has no image in it, we load our default image. If the tag has an image in it, that image is used as for the button graphic.
    addthis.button(target(s), [configurationObject], [sharingObject]);
    Examples
    Render a button at a tag:
    <a id="atbutton"></a>
    
    <script type="text/javascript">
    addthis.button("#atbutton");
    </script>
    Render a button at every anchor with a certain class:
    <a class="sharing-button"></a>
    .
    .
    .
    <a class="sharing-button"></a>
    .
    .
    .
    <a class="sharing-button"></a>
    <script type="text/javascript">
    addthis.button('.sharing-button');
    </script>
    Each "sharing-button"-classed anchor would become a regular AddThis button.
    Share many different blog posts:
    <a id="blog-post-24"></a>
    <script type="text/javascript">
    addthis.button('#blog-post-24', {}, {url: "http://example.com/blog/24", title: "The 24th post"});
    </script>
    .
    .
    .
    <!-- blog content -->
    .
    .
    .
    <a id="blog-post-25"></a>
    <script type="text/javascript">
    addthis.button('#blog-post-25', {}, {url: "http://example.com/blog/25", title: "The 25th post"});
    </script>
    .
    .
    .
    Render a button at an HTML element passed by reference:
    <a id="button-1"></a>
    <script type="text/javascript">
    addthis.button(document.getElementById('button-1'));
    </script>
    Render a button at an array of HTML elements:
    <a id="button-1"></a>
    <a id="button-2"></a>
    <a id="button-3"></a>
    <a id="button-4"></a>
    <script type="text/javascript">
    addthis.button([document.getElementById('button-1'),
                    document.getElementById('button-2'),
                    document.getElementById('button-3'),
                    document.getElementById('button-4')]);
    </script>

    Rendering with Link Decoration

    While the JavaScript rendering methods are powerful, in most cases we believe they're more powerful than what's actually necessary. Following the principles of Unobtrusive JavaScript as discussed above, you can now create and configure an AddThis button in three simple steps:
    • Add plain old anchor tags where you want your buttons to appear
    • Add the appropriate CSS classes for the kinds of buttons you want them to be
    • Add our JavaScript
    Upon loading, our script will look for all our standard classes and render buttons as specified. Here's some simple examples to demonstrate: A button: Share The code used to generate it: <a></a> An email button: The code used to generate it: <a></a> See where we're going with this? The links aren't processed until after the DOM's ready, so it won't even slow down your page. (If you don't want your layout to shift when the images are loaded, however, you should make sure to provide static images or content for all the links.)
    Decoration Class Reference
    Name Description Live example
    addthis_button Standard AddThis button; loads our regular button image if no image is present. Mousing over this button reveals the compact menu. Clicking it opens the expanded menu. Share
    addthis_button_email Email-only button
    addthis_button_service One-click sharing to a particular service, where service could be the service code of any service we support
    addthis_toolbox Standard AddThis Toolbox (requires child elements)
    addthis_default_style When set, toolboxes and other buttons will be rendered floating left, per our standard distribution see above
    addthis_button_compact Same as addthis_button, except only a small + logo is used as a default image. Share
    addthis_button_expanded Same as addthis_button_compact, except mousing over the button has no effect. More Services
    addthis_separator Adds a few pixels of padding around a floating separator, for use in toolboxes. Only intended for spans.
    LEFT|RIGHT
    Note: Class-based configuration trumps global JavaScript configuration objects. For example:
    <script type="text/javascript">
    var addthis_config = {
        ui_click: true /* normally would disable mouseover behavior */
    }
    </script>
    
    <div class="addthis_toolbox"></div>
    <a class="addthis_button_compact">Share</a>
    The compact menu button rendered by this code will have mouseover behavior, as the class-based configuration is considered authoritative.

    Attribute-based Configuration

    So you've probably noticed that the JavaScript-based configuration and the decoration-based rendering only work together for global configurations. If you want different configurations for each button, you can't pass a JavaScript configuration object in to the default renderer. You can, however, specify parameters as custom attributes on the anchors themselves. All the parameters described above are available, with the prefix addthis:. Let's look at some examples: To specify a custom URL and title:
    <a class="addthis_button" addthis:url="http://example.com" addthis:title="An excellent website"></a>
    To specify a hover delay:
    <a class="addthis_button" addthis:ui_hover_delay="200"></a>
    Note: Attribute-based configuration trumps global JavaScript configuration objects.

    Configuration Inheritance

    Configuration is inherited by the elements nested within toolbox divs. This way, you could easily customize an entire toolbox without having to add configuration attributes to every single button. For example:
    <div class="addthis_toolbox" addthis:url="http://example.com/blog/post/2009/05/01" addthis:title="Hooray!">
    <a class="addthis_button_compact">Share</a>
    <a class="addthis_button_email"></a>
    <a class="addthis_button_facebook"></a>
    <a class="addthis_button_buzz"></a>
    </div>
    Each of the buttons in this toolbox would share the URL specified at the toolbox level. There are two exceptions. 1. Configuration isn't inherited by children of arbitrary elements. In this example, neither button would share "http://example.com". The parent div must be an addthis_toolbox.
    <div addthis:url="http://example.com">
    <a class="addthis_button_email"></a>
    <a class="addthis_button_print"></a>
    </div>
    2. Configuration isn't inherited by regular addthis_buttons. Because addthis_button is intended to stand alone, it does not inherit from a toolbox parent.
    <div class="addthis_toolbox" addthis:url="http://example.com">
    <a class="addthis_button"></a>
    </div>

    Valid XHTML

    If you're using XHTML, the custom attributes will not pass validation. To make your XHTML technically valid, you'll need to add a custom namspace declaration to your opening <html> tag. (Note that the W3C validator does not take custom namespaces into account.) Change
    <html xmlns="http://www.w3.org/1999/xhtml">
    to
    <html 
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:addthis="http://www.addthis.com/help/api-spec">

  • Pomodoro - 敏捷时间管理

    9 year(s) ago

    长话短说,我们主要介绍下Pomodoro的学习资料:
    
    书: 45-page book
    
    Cheat Sheet: one-page cheat sheet
    
    网站: The Pomodoro Technique website.
    
    A personal time management approach known as The Pomodoro Technique is becoming quite popular with agile practitioners. Pomodoro includes a number of practices similar to those used by an agile team: time-boxing, frequent opportunities to inspect-and-adapt, estimation, a preference for low-tech tools, and an emphasis on maintaining a sustainable pace.
    
    Francesco Cirillo began developing the technique in the 80's, while he was a student. He was looking for a way to improve the quality of his study time and cut down on the distractions and interruptions that kept him from focusing.
    
    So I made a bet with myself, as helpful as it was humiliating: “Can you study – really study - for 10 minutes?” I needed objective validation, a Time Tutor, and I found one in a kitchen timer shaped like a pomodoro (the Italian for tomato).
    Over the next few years the technique evolved until about 1992, when it took the basic form that it still holds today. In Pomodoro, work is accomplished in uninterrupted 25-minute sessions called Pomodoros. At the end of each Pomodoro, there is a short break. After every set of 3 or 4 Pomodoros, there is a longer break. The technique includes some lightweight planning and tracking as well. At the beginning of the day, a list of the day's objectives is created and then estimated in terms of how many Pomodoros it will take to accomplish. Tasks that will take more than seven Pomodoros should be broken down. Tasks that will take less than one Pomodoro should be grouped together until there is a full Pomodoro's worth. Interruptions and distractions are dealt with by quickly recording them in a way that they can be handled after the current Pomodoro is over. On the rare occasions when an interruption can't be handled in this manner, the current Pomodoro is stopped and considered void. As Francesco says, the next Pomodoro will go better. Over the last couple of years, the Pomodoro Technique has caught the attention of the agile community. Staffan Noteberg's session on the technique was so popular at Agile2008 that it was selected to be re-run at the end of the conference. At Agile2009 Staffan again presented on the technique, as did Renzo Borgatti with a session called: You say tomato, I say Pomodoro.

  • 关于 Erlang 与 Haskell 的语言对比

    9 year(s) ago

    Summary
    John Hughes has ported QuickCheck from Haskell to Erlang. In this interview, he contrasts the two languages, outlining features that he finds more attractive in each of them. He also explains how QuickCheck works and what makes it different from unit tests.
    
    Bio
    John Hughes is co-founder and CEO of Quviq AB, and the creator of QuickCheck. He was also involved in the design of Haskell being co-chair of the committee defining the language. He currently divides his time between his academic involvement as Chair of Chalmers University, Gothenburg, and QuviQ, the company promoting QuickCheck.
    
    About the conference
    The Erlang Factory is an event that focuses on Erlang - the computer language that was designed to support distributed, fault-tolerant, soft-realtime applications with requirements for high availability and high concurrency. The main part of the Factory is the conference - a two-day collection of focused subject tracks with an enormous opportunity to meet the best minds in Erlang and network with experts in all its uses and applications.
    
    视频观看地址: http://www.infoq.com/interviews/Erlang-Haskell-John-Hughes
    

  • magento 1.4 新功能提示 - 模板结构变化

    9 year(s) ago

    magento 1.4版本采用的结构不再是原来的平行
    
    default/
    
    etc/
    
    locale/
    
    template/
    
    your_theme/
    
    etc/
    
    locale/
    
    template/
    
    这样的结构.
    
    估计很多程序员乱去修改default代码,导致系统升级的僵化,失去了magento模板框架设计的初衷,因此这次版本把default的模板偷偷的放到了 base 里面 ,注意这个base是个package,也就是我们经常看到/default/default/中的第一个default.
    
    这次的这个改变虽然不大,但是隐含的意思是告诉开发和设计人员,不要去随意修改base目录的东西. 这为保证我们系统以后平滑过渡和测试功能提供很好的方法. 因为以后你不能知道升级是否因为你的定制产生错误,还是默认就有错误. 好的方法为你产生好的回报.
    
    另外,这个结构我们也可以发现包管理的重要性. 自己公司的模板可以很好的放在一套包里面进行保护,操作性好的话,正如我们有的大客户那样,制作几套模板,互相可以调用,最大化实现界面的公用.节省开发和测试的时间.
    
    圣诞刚过,新年已到,通过模板的多套设定,可以很快改变样式和效果.这样牢牢扣住访客的眼球和留下深刻的印象.
    
    我们祝大家新年快乐,工作顺利!
    

  • magento 1.4 新功能提示 - 后台索引更新

    9 year(s) ago

    之前大家诟病的索引更新这次统一放置在index management里面.这样索引更新可以很方便的进行操作.
    
    到底和之前有多大区别呢?
    
    举例,以前如果要更新存货状态的缓存是通过人工来强制操作点击的.
    
    现在系统由于对flat catalog做了进一步优化,因此系统在更新的厄时候是每次保存的时候触发的.当然这个触发是根据写的索引管理条目来实现,默认的8个索引更新都是保存时更新.
    
    如果大家发现更新不及时也可以在系统的这个菜单进行强制手动更新.系统本身也会提示你更新这些数据.我们发现大家的系统有一些是不会去做库存管理的,那么产品属性,产品价格,相关产品索引这些就是需要经常关注的了.这些索引关系到系统的性能和数据的准确性.
    
    这样再也不会遇到索引出现问题的情况了.
    

  • magento 1.4 新功能提示 - Compilation 代码(预)编译

    9 year(s) ago

    其实这个功能不是新的功能,为什么要放在这里是因为原来的 Compliation(beta) 中的beta字样被去掉了.
    
    一方面是系统比较稳定,另一方面经过我们实际测试,的确和外部模块的冲突最大减少了.例如我们做过一个倒计时模块,原来和编译功能冲突,现在通过开启这个,已经完全没有问题了.
    
    在这里我们需要阐述给大家的是一个对这个功能的解释:
    
    这个功能的原理是减少zend这个庞大库的include操作时候产生的性能开销.那么通过预编译(伪)就可以避免运行时(runtime)的代价了.
    
    那么大家是不是一定要开启这个功能呢?
    
    回答是绝对要开启.
    
    问题是要在生产环境开启,不要在生成环境就开好了,那样容易发现不了问题.另外如果遇到问题一定是你定制的代码有问题,没法预编译了.这个时候需要改代码为magento风格. 所以大家代码风格一定要好,需要遵从magneto的模块开发方法来.
    

  • magento 1.4 新功能提示 - 多站架设(非冗余)

    9 year(s) ago

    这个版本对多站开发系统从技术上进一步提高. 我们可以很方便的把magento的多站做到唯一数据库源,唯一代码源.不再需要原来的冗余代码部署代价.因为多个冗余代码部署的消耗在于负载很难均衡. 你不知道任何一个子站的访问量是否会爆发,也无法控制这个情况.
    
    通过单代码源,你的代码opcode一次加载,可以最大效果的保证性能提高. 如果你的网站访问非常频繁,你可以部署多个服务器,这个多站结构可以让你mysql服务器分离.多个数据库服务器做成一个数据池. 一个负责read,一个负责write. 通过不同的引擎保证读写各自效率最高.并用memcache来进一步提高多站时候数据缓存,保证服务器间沟通减少.
    
    如果您需要这类需求,请联系我们:
    
    邮件:sales@cosmocommerce.com
    
    电话: +86-021-66346672
    

  • 关于ie8的兼容性模式

    9 year(s) ago

    如果不想看原理和其他最好的操作方式例如apache和iis控制兼容模式,那么你可以直接复制下面的放在header中间.
    
    
    
      <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
    Document Compatibility defines how Internet Explorer renders your Web pages. This article explains document compatibility, how to specify the document compatibility mode for your Web pages, and how to determine the document mode of a Web page.

    Introduction

    To help ensure that your Web pages have a consistent appearance in future versions of Internet Explorer, Internet Explorer 8 introduces document compatibility. An extension of the compatibility mode introduced in Microsoft Internet Explorer 6, document compatibility enables you to choose the specific rendering mode that Internet Explorer uses to display your Web pages. This article describes the need for document compatibility, lists the document compatibility modes available to recent versions of Internet Explorer, and shows how to select specific compatibility modes.

    Understanding the Need for Document Compatibility

    Each major release of Internet Explorer adds features designed to make the browser easier to use, to increase security, and to more closely support industry standards. As Internet Explorer gains features, there is a risk that older Web sites may not display correctly. To minimize this risk, Internet Explorer 6 allowed Web developers to choose the way Internet Explorer interpreted and displayed their Web pages. "Quirks mode" was the default; it displayed pages as if they were viewed with older versions of the browser. "Standards mode" (also known as "strict mode") featured the most support for industry standards; however, to take advantage of this enhanced support, Web pages needed to include an appropriate <!DOCTYPE> directive. If a site did not include a <!DOCTYPE> directive, Internet Explorer 6 would display the site in quirks mode. If a site contained a valid <!DOCTYPE> directive that the browser did not recognize, Internet Explorer 6 would display the site in Internet Explorer 6 standards mode. Because few sites already included the <!DOCTYPE> directive, the compatibility mode switch was highly successful. It allowed Web developers to choose the best time to migrate their sites to standards mode. Over time, many sites began to rely on standards mode. They also began to use the features and behavior of Internet Explorer 6 to detect Internet Explorer. For example, Internet Explorer 6 did not support the universal selector; some Web sites used this as a way to serve specific content to Internet Explorer. Internet Explorer 7 offered new features, such as universal selector support, designed to more fully support industry standards. Because the <!DOCTYPE> directive only supports two settings (quirks mode and standards mode), Internet Explorer 7 standards mode replaced Internet Explorer 6 standards mode. As a result, sites that relied on the behavior of Internet Explorer 6 standards mode (such as lack of support for the universal selector) failed to detect the new version of the browser. As a result, Internet Explorer-specific content was not served to Internet Explorer 7 and these sites were not displayed as intended. Because Internet Explorer 7 only supported two compatibility modes, the owners of affected sites were forced to update their sites to support Internet Explorer 7. Internet Explorer 8 more closely supports industry standards than any previous version of the browser. Consequently, sites designed for older versions of the browser may not display as intended. To help mitigate any problems, Internet Explorer 8 introduces the concept of document compatibility, which lets you specify the versions of Internet Explorer that your site is designed to support. Document compatibility adds new modes to Internet Explorer 8; these modes tell the browser how to interpret and render a Web site. If your site does not display correctly in Internet Explorer 8, you can either update the site to support the latest Web standards (preferred) or you can force Internet Explorer 8 to display your content as if it were being viewed in an older version of the browser. This is done by using the meta element to add an X-UA-Compatible header to your Web pages. This allows you to choose when to update your site to support new features supported by Internet Explorer 8.

    Understanding Document Compatibility Modes

    Internet Explorer 8 supports a number of document compatibility modes that enable different features and can affect the way content is displayed.
    • Emulate IE8 mode tells Internet Explorer to use the <!DOCTYPE> directive to determine how to render content. Standards mode directives are displayed in Internet Explorer 8 standards mode and quirks mode directives are displayed in IE5 mode. Unlike IE8 mode, Emulate IE8 mode respects the <!DOCTYPE> directive.
    • Emulate IE7 mode tells Internet Explorer to use the <!DOCTYPE> directive to determine how to render content. Standards mode directives are displayed in Internet Explorer 7 standards mode and quirks mode directives are displayed in IE5 mode. Unlike IE7 mode, Emulate IE7 mode respects the <!DOCTYPE> directive. For many Web sites, this is the preferred compatibility mode.
    • IE5 mode renders content as if it were displayed by Internet Explorer 7's quirks mode, which is very similar to the way content was displayed in Internet Explorer 5.
    • IE7 mode renders content as if it were displayed by Internet Explorer 7's standards mode, whether or not the page contains a <!DOCTYPE> directive.
    • IE8 mode provides the highest support available for industry standards, including the W3C Cascading Style Sheets Level 2.1 Specification World Wide Web link and the W3C Selectors API World Wide Web link, and limited support for the W3C Cascading Style Sheets Level 3 Specification (Working Draft) World Wide Web link.
    • Edge mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 8, this is equivalent to IE8 mode. If a (hypothetical) future release of Internet Explorer supported a higher compatibility mode, pages set to edge mode would appear in the highest mode supported by that version. Those same pages would still appear in IE8 mode when viewed with Internet Explorer 8.
    Because edge mode documents display Web pages using the highest mode available to the version of Internet Explorer used to view them, it is recommended that you limit their use to test pages and other non-production uses.

    Specifying Document Compatibility Modes

    To specify a document mode for your Web pages, use the meta element to include an X-UA-Compatible http-equiv header in your Web page. The following example specifies Emulate IE7 mode compatibility.
    <html>
    <head>
      <!-- Mimic Internet Explorer 7 -->
      <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" >
      <title>My Web Page</title>
    </head>
    <body>
      <p>Content goes here.</p>
    </body>
    </html>
    The content attribute specifies the mode for the page; to mimic the behavior of Internet Explorer 7, specify IE=EmulateIE7. Specify IE=5, IE=7, or IE=8 to select one of those compatibility modes. You can also specify IE=edge to tell Internet Explorer 8 to use the highest mode available. The X-UA-compatible header is not case sensitive; however, it must appear in the Web page's header (the HEAD section) before all other elements, except for the title element and other meta elements.

    Configuring Web Servers to Specify Default Compatibility Modes

    Site administrators can configure their sites to default to a specific document compatibility mode by defining a custom header for the site. The specific process depends on your Web server. For example, the following web.config file enables Microsoft Internet Information Services (IIS) to define a custom header that automatically renders all pages in IE7 mode.
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.webServer>
        <httpProtocol>
          <customHeaders>
            <clear />
            <add name="X-UA-Compatible" value="IE=EmulateIE7" />
          </customHeaders>
        </httpProtocol>
      </system.webServer>
    </configuration>
    If you specify a default document compatibility mode using your Web server, you can override that setting by specifying a different document compatibility mode in a specific Web page. The mode specified within the Web page takes precedence over the mode specified by the server. Consult the documentation of your particular Web server for information on specifying custom headers. Or, for more information, see:

    Determining Document Compatibility Mode

    To determine the document compatibility mode of a Web page using Internet Explorer 8, use the documentMode property of the document object. For example, typing the following into Internet Explorer 8's Address bar displays the document mode for the current Web page.
    javascript:alert(document.documentMode);
    The documentMode property returns a numeric value corresponding to the page's document compatibility mode. For example, if a page has chosen to support IE8 mode, documentMode returns the value 8. The compatMode property introduced in Internet Explorer 6 is deprecated in favor of the documentMode property introduced in Internet Explorer 8. Applications that currently rely on compatMode continue to work in Internet Explorer 8; however, they should be updated to use documentMode. If you wish to use JavaScript to determine a document's compatibility mode, include code that supports older versions of Internet Explorer, as shown in the following example.
    engine = null;
    if (window.navigator.appName == "Microsoft Internet Explorer")
    {
       // This is an IE browser. What mode is the engine in?
       if (document.documentMode) // IE8
          engine = document.documentMode;
       else // IE 5-7
       {
          engine = 5; // Assume quirks mode unless proven otherwise
          if (document.compatMode)
          {
             if (document.compatMode == "CSS1Compat")
                engine = 7; // standards mode
          }
       }
       // the engine variable now contains the document compatibility mode.
    }

    Understanding Content Attribute Values

    The content attribute is flexible in that it accepts values other than the ones described previously. This allows you greater control over the way Internet Explorer displays your Web pages. For example, you can set the content attribute to IE=7.5. When you do this, Internet Explorer attempts to convert the value to a version vector and selects the mode closest to that result. In this case, Internet Explorer would be set to IE7 mode. The following examples show the modes selected for other values when there are no other mitigating factors.
    <meta http-equiv="X-UA-Compatible" content="IE=4">   <!-- IE5 mode -->
    <meta http-equiv="X-UA-Compatible" content="IE=7.5" > <!-- IE7 mode -->
    <meta http-equiv="X-UA-Compatible" content="IE=100" > <!-- IE8 mode -->
    <meta http-equiv="X-UA-Compatible" content="IE=a" >   <!-- IE5 mode --> 
    
    <!-- This header mimics Internet Explorer 7 and uses 
         <!DOCTYPE> to determine how to display the Web page -->
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" >
    Note The previous example shows the results of individual content values. In practice, Internet Explorer only respects the first X-UA-Compatible header in a Web page.
    You can also use the content attribute to specify multiple document compatibility modes; this helps ensure that your Web pages are displayed consistently in future versions of the browser. To specify multiple document modes, set the content attribute to identify the modes you want to use. Use a semicolon to separate each mode. If a particular version of Internet Explorer supports more than one requested compatibility mode, it will use the highest available mode listed in the header's content attribute. You can use this fact to exclude specific compatibility modes, although this is not recommended. For example, the following header excludes IE7 mode.
    <meta http-equiv="X-UA-Compatible" content="IE=5; IE=8" >

    Controlling Default Rendering

    When Internet Explorer 8 encounters a Web page that does not contain an X-UA-Compatible header, it uses the <!DOCTYPE> directive to determine how to display the page. If the directive is missing or does not specify a standards-based document type, Internet Explorer 8 displays the page in IE5 mode (quirks mode). If the <!DOCTYPE> directive specifies a standards-based document type, Internet Explorer 8 displays the page in IE8 mode, except in the following cases:
    • Compatibility View is enabled for the page.
    • The page is loaded in the Intranet zone and Internet Explorer 8 is configured to pages in the Intranet zone in Compatibility View.
    • Internet Explorer 8 is configured to display all Web sites in Compatibility View.
    • Internet Explorer 8 is configured to use the Compatibility View List, which specifies a set of Web sites that are always displayed in Compatibility View.
    • The Developer Tools are used to override the settings specified in the Web page.
    • The Web page encountered a page layout error and Internet Explorer 8 is configured to automatically recover from such errors by reopening the page in Compatibility View.
    For more information, see Internet Explorer Blog: Compatibility View Recap World Wide Web link.
    Note When configured to load Intranet pages in Compatibility View, Internet Explorer makes an exception for pages loaded using the localhost address or a loopback address. Pages loaded using one of these techniques are displayed in IE8 mode when the <!DOCTYPE> directive specifies a standards-based document type.
    In addition, the following registry key allows you to control the way Internet Explorer handles pages that do not contain X-UA-Compatible headers.
    HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER) SOFTWARE Microsoft Internet Explorer Main FeatureControl FEATURE_BROWSER_EMULATION iexplore.exe = (DWORD)
    The DWORD value must equal one of the following values.
    Value Description
    7000 Pages containing standards-based <!DOCTYPE> directives are displayed in IE7 mode.
    8000 Pages containing standards-based <!DOCTYPE> directives are displayed in IE8 mode.
    8888 Pages are always displayed in IE8 mode, regardless of the <!DOCTYPE> directive. (This bypasses the exceptions listed earlier.)
    By default, applications hosting the WebBrowser Control open standards-based pages in IE7 mode unless the page contains an appropriate X-UA-Compatible header. You can change this by adding the name of the application executable file to the FEATURE_BROWSER_EMULATION feature control key and setting the value accordingly.

    Conclusion

    Compatibility is an important consideration for Web designers. While it's best to create sites that do not rely on specific behaviors or features of a Web browser, there are times when this is not possible. The document compatibility mode ties a Web page to the behavior of a specific version of Internet Explorer. Use the X-UA-Compatible header to specify the versions of Internet Explorer that your pages support. Use document.documentMode to determine the compatibility mode of a Web page. By choosing to support a specific version of Internet Explorer, you can help ensure that your pages will display consistently in future versions of the browser.

  • 关于zend server对drupal和magento的性能优化

    9 year(s) ago

    以下是drupal的优化情况:
    
    http://static.zend.com/topics/Optimizing-Drupal-Performance-Zend-Acquia-Whitepaper-Feb2010.pdf
    
    以下是magento的优化情况:
    
    http://static.zend.com/topics/Magento-and-Zend-Server-performance-benchmarks.pdf
    
    这两篇文章(官方软文)可以给你一个清晰的感觉,zend server在对缓存和bytecode优化上面处理的能力.
    
    相对apc来说,zend server的bytecode的确有微弱优势,但是付费版的page cache才是他最强大的地方,如果开启于drupal7的情况下,几乎可以媲美静态html页面的速度.
    
    我们认为如果您有财力支持请尽可能购买zend server来优化性能,如果预算有限可以使用zend server社区版或者apc/xcache等来优化. 有能力的可以更新zend框架版本和针对框架代码里面的性能较差部分进行优化.使之适合magento运行,毕竟框架不仅仅考虑的是magento,更多的是考虑泛化需求.
    

  • CI 持续集成与GIT分布式开发

    9 year(s) ago

    CI持续集成在敏捷开发有巨大意义。
    
    通过实施CI持续集成,我们可以保证客户的反馈尽早获得,与客户进行“现场”需求分析。
    
    但是由于传统版本控制工具在多人提交时候会出现效率下降,因此持续集成(也即快速反馈需求)的一个关键实现目标就是有一个快速高效的版本控制工具,在这点上git要比svn有优势。
    
    首先他是一个离线式的版本控制工具,本地和服务器都可以进行提交。那么在关键性的地方我们可以进行提交,集成确认问题。
    
    在实际项目实施过程中。我们发现:
    
    hudson作为持续工具很好很强大,针对其接口进行二次扩展可以很方便的完善系统的开发和应用。 不仅仅体现在版本控制,发布管理,还可以实现项目自动生成,变更。
    
    通过api远程获得数据,组装对应的产成品也不是问题。(当然这个脱离了其初衷了)
    

  • 关于php下代码质量控制-sonar

    9 year(s) ago

    我们在前一篇文章已经分享了持续构建代码和分布式版本控制带来的好处。
    
    但是没有一个好的机制去进行代码质量控制,显然前者带来的好处是没有太大价值的。
    
    因此引入一套代码质量评估工具尤其关键。
    
    在hudson系统我们每次提交代码后可以进行自动构建,生成评估代码分析。最终给代码审核以及主管了解项目质量状况。
    
    从长期项目维护性和复用性角度来说sonar可以提供的控制方面非常全面。
    
    php代码需要评估的部分包括:
    
    1  复杂度:
    
    代码行,类数量,方法数量,文件数
    
    2  维护性和代码冗余:
    
    评论比例,重复代码数量
    
    3 代码质量:
    
    单元测试覆盖率,测试成功情况
    
    4 代码约定
    
    通过以上几个方面评估后。sonar会给主管人员一个非常方便的结论。
    
    当然这个工具在分析大型系统也是非常缓慢的,我们在分析magento(不包括zend类库)的时候,发现系统计算较长时间。但是获得的结果是非常有价值的。
    
    通过这个软件,我们觉得有必要进行深入研究,对我们以后开发插件,确保代码可维护性和可扩展性。
    

Items 1 to 20 of 40 total

per page

Set Ascending Direction