仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1741|回复: 19
打印 上一主题 下一主题

[学习教程] PHP编程:php在母语方面的撑持(转载)

[复制链接]
小魔女 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-4 00:15:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
学习数据库了,MYSQL可算是PHP的黄金搭档了,不过,虽然话是这么说,你也可能恨不得把MYSQL给生吞活剥了,因为这一行一列的东东简直让自己头晕目眩。   Native Language Support
PHP is a great language for developing dynamic web sites. Some do it for fun while others for business. It is true that a great part of the web is in English. However, if you are targeting a worldwide audience, then neither English nor Esperanto alone is an option.

If you need to deliver content in several languages, it is a good idea to explore several alternatives. However, some alternatives may not be suitable for dynamic websites. Added to that, there is the overhead of time spent in maintenance. To further complicate things, your needs may not be totally in line with the resources you have at your disposal. Therefore, it is advisable to choose an alternative that suits you best.

I found myself in positions which required me to deliver content in both English and Spanish, and in one project a third language. Here are the possibilities I explored:

Explicit links for each language
Use Apache's mod_negotiation
Use GNU Gettext support in PHP
Write your own
This article gives a brief introduction to the first three possibilities, but then we will go about the fourth solution which suited the requirements best, given the set of constraints. I am assuming that the reader is at least familiar with PHP programming and the use of PHP classes.


Principles of content negotiation
Before we go into exploring the various options, we should understand the basics of content negotiation and how that applies to the development framework. Then, you will be able to develop a web application that can deliver its content in the language of choice of your visitor.

By simply configuring the web browser, the user can set it up in a way that his or her preferred language is used when available. Several languages can be specified in a prioritized list, by setting up the preferences or option of the browser.

ands this list of preferred languages on every request made to the site. This action is totally transparent to the user, as the information gets sent in the Accept-Language header, for example:

Accept-Language: bg, es, en-US, fr

Here our visitor has chosen Bulgarian, US English, Spanish and French in that order. Notice that you can even specify regional variants. The first two characters are a language code as specified in an ISO standard. This language code may be followed by a dash and a region code.

As an example, if the request arrives to a website whose content is entirely in Russian, then the list is exhausted and the visitor will get Russian text whether (s)he likes it or not. Now, assuming the website has both English and Spanish content (the 2nd and 3rd options), then the visitor will receive pages in Spanish. Why? Simply because here Spanish had higher priority with respect to English.

Sometimes, the web server itself can manage the content negotiation, if configured to do so. Otherwise, the request for a particular language is ignored. Alternatively, the application that delivers the content takes the decision of which language it is to use. This is exactly what we will do later.

Before going further, I would like to point out that the content negotiation is not just dealing with human languages. For example, it also negotiates the kind of information the client can take by means of MIME types, but that is beyond the scope of this article.
Explicit links
Many multi-lingual websites present the content in various languages, and do so by placing a link on the document. There would be one link for each of the supported languages. This is a very simplistic approach and should only be used if you need to have multi-lingual content, but do not have the resources of a scripting language or dynamic content.

If a document is moved, or a new language is added or removed from the repertoire, then the webmaster would have to edit, add or remove links in each of the affected documents. This can be quite tedious.


Apache's content negotiation
The Apache web server can manage language-sensitive content delivery by using the information from the content negotiation headers. Then, the webmaster must provide the static pages for each language and name them properly. For example if the welcome page is available in Spanish and English, the webmaster would have these two files:

welcome.html.es welcome.html.en

When the web server is well configured, it will deliver the appropriate web page based on the language code according to the priority list.

This works perfectly for static pages. However, if you have a dynamic website where a great deal of the pages is generated based on queries, then this approach will not work. Another disadvantage is that you need to know how to do it and you may or may not have access to the configuration files. My experience was that it was a bit tricky and it did not offer enough flexibility for my purposes.

An advantage of this method is that the negotiation is between the browser and the Apache server. You need only to provide the static content.


GNU Gettext with PHP
This internationalization tool has been around for some time for C programmers. There is also a variant used on other Un*x, such as HP. Both are very good and are easy to use.

This extension has been available in PHP since version 3.0.6 and also in 4.0. The Gettext extension is easy to use, and is good if you are generating your webpages dynamically. The only thing left here would be the PHP code that generates the content and a set of message catalogs. Supporting a new language is as easy as generating a new catalog with the translations and dropping the file in the appropriate directory. Therefore, assuming you have a PHP application named "myphp" and that the appropriate message catalogs exist and are installed, then the application would have something like this:

<?php

/* Initialization of GetText in myphp */
putenv("LANG=$language");
bindtextdomain("myphp","./locale");
textdomain("myphp");
/* Print some messages in the native language */
echo gettext("Hello new user");
echo _("You have no new messages");
              
?>

My provider had recently upgraded from PHP 3.0RC5 to a PHP4.0 Beta 2 installation. While PHP4 does have support for the Gettext extension, my provider did not compile the PHP4 module with Gettext support. However, even if they had, moving to another provider without Gettext would become a major headache.

CtNls - National Language Support
Having considered various alternatives, I wrote down a set of requirements for the NLS module:


It had to be simple, and based in PHP
Easy to use
Allow the user the freedom of choosing or mixing NLS methods
As a result, I developed a PHP class that would allow the user to set up a multi-lingual website. With this class, the developer can emulate the Apache approach of one file per language, without reconfiguring Apache. Additionally, it is possible to use a PHP script that generates the output in the appropriate language by means of message catalogs.

A real life application of this class is on my website at http://www.coralys.com/ The main page is available in English (en), Spanish (es) and Dutch (nl).


Using CtNls
This class is very easy to use. The application would have something like this in its initialization code:
<?php

include('ctnls.class.php');

$nls = new CtNls;
            
?>

At that point, the class has detected the choice of languages suggested by the user behind the browser. What happens next depends on which method the application uses to provide multi-lingual content.

For static web pages, the approach is similar to the Apache convention. The name of the webpage comprises three parts: the base name, the language extension (two letter code per ISO standard) and the extension which would typically be ".html". For example a welcome page would be:

welcome.en.html welcome.es.html

Notice that each page contains a different language. At this point, your PHP application would serve the file in the appropriate language, by specifying the whole name without the language ID/code. The CtNls class inserts the appropriate ID/code:

<?php

$nls->LoadPage("welcome.html");
   
?>

Here you can specify any filename that is valid to the PHP virtual() function, which is how LoadPage() delivers the content to the browser.

Another way to deliver the content in various languages is by using message catalogs. In this case, there is one PHP file for each language. It must be a valid PHP file because the message catalog is nothing more than a collection of PHP constants, each referring to a particular message. The reasons why we use constants and not variables are twofold. First, the message does not change and by definition it is a constant. Second and most important, is that in PHP, constants are accessible at any place, even within functions. Whereas, if we use variables for the messages, we would have to resort to using a "global" declaration for each message used within a function.

The catalogdir class variable specifies the location of all message catalogs. It is an absolute path within the server, where each application will have its message catalog. The name of each catalog file has three parts: the application ID, the language code and a valid PHP extension so that it can be include()ed by CtNls.

Now, assuming we have an application called "myapp," we could use the following code at the initialization part:

<?php

$nls->LoadMessages("myapp");

?>

This, as well as LoadPage(), can only be used after you have created a new instance of the CtNls object. This method expects at least one file (with the default language) in the message catalog. In this case, myapp.en.php, and inside, it must have valid constant declarations for each message. For example:

<?php

// Language: English
// File:  path/to/nls/myapp.en.php
define("MSG_WELCOME", "welcome to our site");
define("MSG_REDIRECTED", "You are being redirected to our new site");

?>

<?php

// Language: Spanish
// File:  path/to/nls/myapp.es.php
define("MSG_WELCOME", "Bienvenido a nuestras paginas");
define("MSG_REDIRECTED", "Esta siendo redireccionado a nuestro " .
"nuevo sitio de web");

?>

Only one of these will be loaded, depending on the language priority assigned by the user. Then, somewhere in the PHP application, you can generate output like this:

<?php

echo MSG_WELCOME . "<br>";
echo MSG_REDIRECTED;

?>

Auxiliary functions
The CtNls class has several auxiliary member functions. These are not normally used, but can come in handy.

The SetCatalogPath function overrides the path to the catalog directory given in the configuration part of the CtNls class.

SetDefaultLanguage does just that. It sets the code of the language to be tried in case all else fails. This is normally English.

SetLanguageId and GetLanguageId set and return the id/code of the first language to check. This language is checked before any of those found in the user preferences. Upon initialization, it is the same as the first language in the user list. Once LoadPage() or LoadMessages() is invoked, GetLanguageId() would return the ID of the language that was used in delivering the content to the browser. It is also useful if the user has stored his/her preference in a cookie.


How it actually works
We have already explained what happens during the content negotiation phase. The browser sends the user's choice of languages in the Accept-Language header. This information is available to any PHP script in the $HTTP_ACCEPT_LANGUAGE global variable.

When you create a new instance of the CtNls object, the constructor function CtNls() takes control. In turn, it initializes some internal settings and calls setLanguage(). This internal member function goes through the list of languages in $HTTP_ACCEPT_LANGUAGE (delimited by commas), by using only the language code and stripping the region code. The language code is for selecting the appropriate file. In this process, we convert the list to an array, but preserve the language priority.

When an application invokes either LoadPage() or LoadMessages(), these methods will call the internal search() function.

The search() member function walks the language preference array from start to finish and if all of them fail to produce results, it checks for the default language. This function keeps track of which languages it tried so that two attempts are not done on the same language.

The getFile() member function is called every time the search() function generates a new language candidate. It does this by passing it a base name, a language candidate and optionally a file extension.

By passing the base name, the language code and the file extension in that order, the getFile() function generates a list of candidate file names. If we are using LoadMessages() and pass it an empty extension name, it produces a list by using all known valid PHP script extensions by prefixing them with the path to the catalog directory. These PHP extension names are currently ".php3" and ".php". If, on the other hand, we pass the file extension to the function, then, we reduce the list of candidate file names to one.

getFile() then continues by walking through the list of candidate file names until it finds one that exists. Based on this, we determine the current language and the object reads in that file.




  总的来说,在这一个月左右的时间中,学到的不少,但是也遇到不少的问题,比如批量图片的上传,一直到现在也不懂,如何实现动态的增加上传图片的数量。
山那边是海 该用户已被删除
沙发
发表于 2015-2-4 10:10:31 | 只看该作者
在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。
admin 该用户已被删除
板凳
发表于 2015-2-6 05:28:47 | 只看该作者
再就是混迹于论坛啦,咱们的phpchina的论坛就很强大,提出的问题一般都是有达人去解答的,以前的帖子也要多看看也能学到不少前辈们的经验。别的不错的论坛例如php100,javaeye也是很不错的。
愤怒的大鸟 该用户已被删除
地板
发表于 2015-2-12 03:45:28 | 只看该作者
如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,
冷月葬花魂 该用户已被删除
5#
发表于 2015-2-22 20:11:43 | 只看该作者
刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。
金色的骷髅 该用户已被删除
6#
发表于 2015-3-7 01:57:40 | 只看该作者
真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎,
不帅 该用户已被删除
7#
发表于 2015-3-14 00:47:47 | 只看该作者
在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。
活着的死人 该用户已被删除
8#
发表于 2015-3-20 22:57:48 | 只看该作者
php是动态网站开发的优秀语言,在学习的时候万万不能冒进。在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理。
爱飞 该用户已被删除
9#
发表于 2015-3-22 20:38:07 | 只看该作者
如果你已经到这种程度了,那么你已经可以做我的老师了。其实php也分很多的区域,
深爱那片海 该用户已被删除
10#
发表于 2015-3-24 03:16:09 | 只看该作者
作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。
简单生活 该用户已被删除
11#
发表于 2015-3-24 10:31:05 | 只看该作者
首先我是坚决反对新手上来就用框架的,因为对底层的东西一点都不了解,造成知识上的真空,会对以后的发展不利。我的观点上手了解下框架就好,代码还是手写。当然啦如果是位别的编程语言的高手的话,这个就另当别论啦。
蒙在股里 该用户已被删除
12#
发表于 2015-3-27 17:17:19 | 只看该作者
遇到出错的时候,我经常把错误信息直接复制到 google的搜索栏,一般情况都是能搜到结果的,不过有时候会搜出来一大片英文的出来,这时候就得过滤一下,吧中文的弄出来,挨着式方法。
再见西城 该用户已被删除
13#
发表于 2015-4-4 01:36:32 | 只看该作者
不禁又想起那些说php是草根语言的人,为什么认得差距这么大呢。
飘灵儿 该用户已被删除
14#
发表于 2015-4-11 04:11:32 | 只看该作者
找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。
小女巫 该用户已被删除
15#
发表于 2015-4-12 15:21:39 | 只看该作者
有时候汉字的空格也能导致页面出错,所以在写代码的时候,要输入空格最好用引文模式。
小魔女 该用户已被删除
16#
 楼主| 发表于 2015-4-14 15:44:07 | 只看该作者
最后介绍一个代码出错,但是老找不到错误方法,就是 go to wc (囧),出去换换气没准回来就找到错误啦。
分手快乐 该用户已被删除
17#
发表于 2015-4-26 21:57:29 | 只看该作者
使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。
再现理想 该用户已被删除
18#
发表于 2015-5-10 01:07:20 | 只看该作者
实践是检验自己会不会的真理。
透明 该用户已被删除
19#
发表于 2015-6-5 02:49:10 | 只看该作者
首推的搜索引擎当然是Google大神,其次我比较喜欢 百度知道。不过搜出来的结果往往都是 大家copy来copy去的,运气的的概率很大。
因胸联盟 该用户已被删除
20#
发表于 2015-6-6 05:01:13 | 只看该作者
我还是强烈建议自己搭建php环境。因为在搭建的过程中你会遇到一些问题,通过搜索或是看php手册解决问题后,你会更加深刻的理解它们的工作原理,了解到php配置文件中的一些选项设置。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 01:56

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表