0

大家好,

我正在尝试使用 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从 URL$_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

为什么会这样?我在做一些概念上的错误吗?问题是我也在locale.phpajax 调用中使用它来获取动态生成的 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;
}

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

谢谢!

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

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

  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;
    }
    

这两个文件都包含在index.php

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

但是,如果我现在使用 ajax 对短语进行本地化,则会出现以下错误消息:

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

这个怎么可能?我以为$_SESSION是超全球的?!?

4

3 回答 3

2

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

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

你也可以考虑看看

$_SERVER['HTTP_ACCEPT_LANGUAGE']

在开始对服务器和客户端进行 ajax ping-pong 以进行初始语言快速猜测之前...


对于您的代码的两个版本,当 session_start位于 locale.php 中时,为什么它可以工作并不神秘。

原因是:

您的 ajax 调用没有从index.php进入您的脚本,而是直接进入api/locale.php

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

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

于 2013-04-20T22:55:15.873 回答
1

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

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

echo loc('foo');

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

于 2013-04-20T23:40:03.317 回答
0

嗨,马库斯,我将尝试在评论中回答您的问题。

$_SESSION id 确实是一个超级全局的。但是您需要调用 session_start() 才能使其正常工作。这就是为什么它在 locale.php 中不再起作用的原因

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


  1. 会话.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. `翻译.php

    函数 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 中)。否则,您将退回到默认语言。

    包括'path_to_translate/translate.php';

    session_start();

    if(isset($_SESSION['lang'] {
    $lang = $_SESSION['lang'];
    } else {
    $lang = 'en';
    }

    $phrase = $_GET['phrase'];

    回声 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> 
    

希望这会有所帮助。当然,我无法测试所有这些代码,所以它们可能是一些错误。但这是一般的想法。
我尽量不改变你所做的太多。但是还有一个问题。您不应该在 index.php 中定义语言。如果您的索引中有一个表格来选择语言。在 ajax 中调用 set_lang.php。不是让索引在会话中设置语言。

于 2013-04-29T17:00:40.647 回答