使用PHP进行国际化 - 执行PHP函数的顺序

时间:2013-04-20 22:31:25

标签: php ajax url session

嘿所有,

我想用php将我的网站国际化。我是PHP的新手!

index.php以此开头:

<?php session_start(); ?>
<?php include 'api/locale.php'; ?>

<html>
  <!-- ... -->
  <div><?php loc('foo') ?></div>

locale.php看起来像这样:

<?php
  if(isset($_GET['lang']) {
      $_SESSION['lang'] = $_GET['lang'];
  } else {
      $_SESSION['lang'] = 'en';     // default value
  }

  // use the necessary language file
  include('/locale/' . $_SESSION['lang'] . '.php');

  // get phrase from URL
  if (isset($_GET["phrase"]))
    loc($_GET["phrase"];);

  function loc($phrase)
  {
    global $lang;

    if(array_key_exists($phrase, $lang)) {
        echo $lang[$phrase];
    } else {
        echo $phrase;
    }
  }
?>

我的想法是想使用函数loc($phrase)来获取德语或英语的内容。但问题出在这里:

如果我有这样的代码,我总是得到英文版,因为在locale.php我无法从网址获取lang$_GET['lang']未定义。因此,会话语言始终设置为默认语言(en)。

但是,如果我将session_start();移到文件locale.php中,国际化就会起作用:

index.php

<?php include 'api/locale.php'; ?>

<html>
  <!-- ... -->
  <div><?php loc('foo') ?></div>

locale.php

<?php
  session_start();
  if(isset($_GET['lang']) {
      $_SESSION['lang'] = $_GET['lang'];
  // ... rest the same as above

为什么会这样?我在做概念错误的事情吗?问题是我也在ajax调用中使用此locale.php来获取动态生成的HTML元素的国际内容:

function loc(phrase)
{
  var locString;
  $.ajax({
    // force synchronous ajax call, to return with locString
    async: false,
    // url with to be translated id
    url: "api/locale.php?phrase=" + phrase,
    // "get" for small data (otherwise post)
    method: "get",
    // callback function after server has reveiced information
    success: function (data)
      {
        locString = data;
      }
  });
  return locString;
}

因此,如果我通过此AJAX调用一遍又一遍地调用locale.php,是不是会有新的会话重复开始?我不确定我是否正确设计了我的功能。我很高兴任何评论!

谢谢!

===============编辑===============

好吧,我现在尝试了一种新的方法:

  1. session.php

    // session starts at this point
    session_start();
    
    // internationalisation in EN and DE
    $allowedLangs = array('en', 'de');
    
    // check lang-parameter given in URL and set language from there
    if(isset($_GET['lang']) && in_array($_GET['lang'], $allowedLangs))
      $_SESSION['lang'] = $_GET['lang'];
    
    if(!isset($_SESSION['lang']))
      $_SESSION['lang'] = 'en';     // default value
    
  2. locale.php

    // include correct languguage file
    $root = realpath($_SERVER["DOCUMENT_ROOT"]) ;
    include($root . '/locale/' . $_SESSION['lang'] . '.php');
    
    // get phrase from URL and translate it
    if (isset($_GET["phrase"]))
    {
      $phrase = $_GET["phrase"];
      global $lang;
    
      if (array_key_exists($phrase, $lang))
        echo $lang[$phrase];
      else
        echo $phrase;
    }
    
  3. 这两个文件都包含在index.php

    <?php include 'api/session.php'; ?>
    <?php include 'api/locale.php'; ?>
    

    但是,如果我现在使用ajax定位短语,则会显示以下错误消息:

    Notice: Undefined variable: _SESSION in ... /locale.php on line 4
    

    怎么会这样?我以为$_SESSION是超全球的?!?

3 个答案:

答案 0 :(得分:2)

当您通过ajax使用session_start调用api / locale.php的版本时,不会是新的但相同的会话将启动,这是正确的行为。

Word启动可能让您感到困惑,但会话启动会正确提供当前会话的信息,而不是新信息。所以没什么值得担心的。

你也可以考虑一下

$_SERVER['HTTP_ACCEPT_LANGUAGE']

在开始ajax ping-pong服务器和客户端之前,用于初始语言快速猜测...

对于代码的两个版本,当session_start为
时,它的工作原理并不是一个谜 在locale.php。

原因是:

你的ajax调用没有从 index.php 输入你的脚本,它直接进入 api / locale.php

如果在api / locale.php 中没有session_start,则ajax调用将进入无会话的php调用。

因此它将保留默认值,因为会话数据既不能被提取也不能被记录。

答案 1 :(得分:1)

我认为你的locale.php文件中存在概念上的错误。 你总是设置$_SESSION['lang']的事实是一种难闻的气味 如果您没有设置$_SESSION['lang']的值并且只使用$_SESSION['lang']的值而不修改它,则应该存在这种情况。
使用您的语言环境文件,以及未将“lang”作为参数传递的ajax调用,您将始终获得默认语言。
但无论如何,你的local.php文件应以session_start();开头,如ishan所述。

顺便说一句,你不应该在你的函数loc中使用'echo'。而是返回结果并执行

echo loc('foo');

它会做同样的工作,但你的loc函数会更可重用。

答案 2 :(得分:0)

嗨马库斯我会尽力在评论中回答你的问题。

$ _ SESSION id确实超级全球化。但是你需要调用session_start()才能工作。 这就是为什么它在locale.php

中不再起作用的原因

问题是您的locale.php文件同时用于两个目的。 它应该只是翻译但不能直接从URL访问。 所以你应该做这样的事情:

  1. session.php文件
    `

    //在这里定义一个默认值。无论发生什么,你都知道$ _session ['lang'] //将始终设置。

    if(! isset ($_SESSION['lang'] {
       $_SESSION['lang'] = 'en';     // default value
    }
    
    // internationalisation in EN and DE
    $allowedLangs = array('en', 'de');
    
    // check lang-parameter given in URL and set language from there
    //if necessary, the default value will be overwritten.
    if(isset($_GET['lang']) && in_array($_GET['lang'], $allowedLangs)) {
      $_SESSION['lang'] = $_GET['lang'];
    }
    
  2. `translate.php

    function getTranslation($ phrase,$ lang ='en'){

     $root = realpath($_SERVER["DOCUMENT_ROOT"]) ;
     include($root . '/locale/' . $lang . '.php');
    
     //the array with the phrases and their translations should not be called $lang 
     //to avoid confusion. Let's call it $translations
     if (array_key_exists($phrase, $translations))
       return $translations[$phrase];
     else
       return $phrase;
     }
    

    }

  3. locale.php ` 该文件将在ajax中调用。 它将提供已经定义的$ _SESSION ['lang'] (例如在index.php中)。否则你会回到默认的lang。

    包括'path_to_translate / translate.php';

    在session_start();

    if(isset($ _ SESSION ['lang'] {
           $ lang = $ _SESSION ['lang'];
       其他{
           $ lang ='en';
       }

    $ phrase = $ _GET ['phrase'];

    echo getTranslation($ phrase,$ lang);

  4. index.php

       session_start(); 
       include 'api/session.php'; 
       include 'path_to_translate/translate.php';
    
       $lang = $_SESSION['lang'];
    
    
    
    <some html>
    
    //to translate anything
    <?php echo getTranslation($anything, $lang)  ?>  
    
    </some html> 
    
  5. 希望这会有所帮助。当然我无法测试所有这些代码,所以他们可能会有些错误。但这是一般的想法 我尽量不改变你所做的事情。但仍有问题。你不应该在index.php中定义lang。如果索引中有表单选择lang。在ajax中调用set_lang.php。索引不是在会话中设置lang。