I want to use the array function of PHP to translate a website. I have created PHP files with arrays in them for all the text to be translated.
<?php
//ESPANOL
$lang = array(
'work' => 'Trabajo'
'packaging' => 'Empaque'
);
And then I am calling them inside my nav.php file, and will in the content section too.
<?php include('includes/languages/es.php'); ?>
<?php echo $lang['work']; ?>
All pretty straight forward.
What I want to know is how to switch between these array files without editing the HTML, so that I don't have to link to another 'index_es.php' etc. I understand that the link would be something like this, but I don't know how this is going to work.
English
I'm guessing I need to include another file that includes the language files and then the link can choose from them but I don't know what the code would be for this.
Would it involve including a 'lang_directory' above the link and then somehow including from there??
**Also I would like to avoid using Zend/Gettext translation becuase I want to learn this inside out.
You can make another dimension containing the target language. Then pass a GET parameter to select that language. If the language isn't recognized you can fallback to English. Here's a sample.
$languages = array(
'en' => array(
'work' => 'work',
'packaging' => 'packaging'
),
'es' => array(
'work' => 'Trabajo',
'packaging' => 'Empaque'
),
);
// default language to use when the requested isn't found
$defaultLanguage = 'en';
// language requested via GET
$requested = $_GET['locale'];
// use the requested language if it exists, otherwise the default language
$language = isset($languages[$requested]) ? $requested : $defaultLanguage;
// our translations
$translation = $languages[$language];
// "work" translated based on the language
echo $translation['work'];
And the link for Español would look like this.
index.php?locale=es
I'd keep your array system, correct the links into something like index.php?lang=en and then include your file depending on the lang parameter:
if ( isset($_GET['lang']) && file_exists('includes/languages/'.$_GET['lang'].'.php') ){
include_once('includes/languages/'.$_GET['lang'].'.php');
}
And if you want to keep the language parameter in your session, do something like this:
if ( isset($_GET['lang']) && file_exists('includes/languages/'.$_GET['lang'].'.php') ){
$_SESSION['lang'] = $_GET['lang'];
}
if ( !isset($_SESSION['lang']) ){
// Default language
$_SESSION['lang'] = 'en';
}
include_once('includes/languages/'.$_SESSION['lang'].'.php');
One way to do this is by using sessions.
Make a lang.php file that will be used to change between languages.
<?php
//Start session
session_start();
//Do we get a lang variable
if (isset($_GET['lang'])) {
//Make sure we only get the lang filename
$lang = basename($_GET['lang']);
//If the file exists, then save it to session
if (file_exists('includes/languages/' . $lang . '.php'))
$_SESSION['lang'] = $lang;
}
//If the client were refered here (via hyperlink) send them back
if (isset($_SERVER['HTTP_REFERER']))
header('location: ' + $_SERVER['HTTP_REFERER']);
?>
In the header of the files you want multiple languages, insert.
<?php
//Start session
session_start();
//Default language
$lang = 'english';
//If the client have set a language, use that instead
if (isset($_SESSION['lang']))
$lang = $_SESSION['lang'];
//Load language file
include('includes/languages/' . $lang . '.php');
?>
The links to change language will then be like this:
Español|English
Out can also take the code from the lang.php file and put in a included file that will be loaded before the inclusion of language file and remove the HTTP_REFERER redirection.
The links to change language will then be like this:
Español|English
Related
I would like to use this concept on my webshop, but how can I send variables through?
(You know index.php? Page = test & variable = 22 // variable does not work)
$page = isset($_GET['Page'])? trim(strtolower($_GET['Page'])) :"front";
$allowedPages = array(
'front' => './include/webshop_frontshop.php',
'logon' => './include/webshop_tjek_login.php',
'test' => './include/webshop_testside.php'
);
include( isset($allowedPages[$page]) ? $allowedPages[$page] : $allowedPages["front"] );
This link works fine!: nywebshop.php?Page=test
This link does not work (says the page does not exist): nywebsite.php?Page=test&item=5
Possible errors:
1) You use spaces in URL (in exemple you did)
2) In php you use $_GET['side'] - not $_GET['Page'] or $_GET['variable']
3) If you want to save variables in all pages after sending, you can use sessions:
$_SESSION['get_saved_param__Page'] = $_GET['Page'];
And it will be good to use standart
if {
// code
} else {
// code
}
As it much easier to read and you will spend most of the time in coding at reading your scripts, not writing.
I'm trying to follow the README file of this translator package, but I'm not sure I'm following… Please be aware that I have VERY LITTLE knowledge of PHP.
I have a project set up something like this:
lang/
--en/language.php
--es/language.php
templates/
--blocks/
----header.php
----[…]
--sections/
----home.php
----[…]
boot.php
index.php // This is where I include my templates and boot.php
My boot.php goes something like this:
<?php
include_once(__DIR__ . '/vendor/autoload.php');
$lang = (!empty($_GET['lang'])) ? $_GET['lang'] : 'es';
use diversen\lang;
use diversen\translate\extractor;
$l = new lang();
$l->setDirsInsideDir(__DIR__ . '/lang/');
$l->setDirsInsideDir(__DIR__ . '/templates/');
$l->loadLanguage($lang);
$e = new extractor();
$e->defaultLanguage = $lang;
$e->updateLang();
// This is just a shortcut function
function __($str) {
return lang::translate($str);
}
By including boot.php in my "main template", index.php, I'd like to add all non-translated strings to their corresponding translation file, but they remain unchanged (ie. nothing is being appended to the translation files)
In my template files I'm using the shortcut function __() like so:
<?= __('Some string to translate'); ?>
And I'm seeing them rendered as NT: Some string to translate. I assume NT stands for Not Translated or something along those lines.
My apache error logs are not showing anything…
Before I start, I am completely new to PHP. This is probably a stupid error and I am probably doing this in the worst way possible.
I have this code:
<?php
if (!isset($_GET['p'])) {
$url .= '?p=home';
header('Location:' . $url);
exit;
}
elseif (!isset($_GET['sp'])) {
header("Location: ".$_SERVER['REQUEST_URI'].'&sp=index.php';);
die();
}
include('/Page/' . htmlspecialchars($_GET["p"]) . '/' . htmlspecialchars($_GET["sp"]));
?>
Basically the url format is www.example.com/?p=PAGE&sp=SUBPAGE.php
The internal format from this will be /Page/PAGE/SUBPAGE.php
Reasons:
Each 'Post' will have it's own folder for it's resources. (?p=) Then they can put anything within their folder and link to it with the SUBPAGE (&sp=).
This keeps everything organised and stops any internal linking to anywhere but the /page/ area.
What's wrong:
If there is no Page (p) set I need to add ?p=home as the default and if their is no SubPage (sp) set I need to add &sp=index.php by default.
If there is no Page then the SubPage will be reset to default.
If you are on a page www.example.com/?p=blog then it will add the subpage without removing the page (?p=blog to ?p=blog&sp=index.php)
However if there is no page then the subpage will be reset to default.
The question:
How can I come about this?
Thank you, in advance.
I would approach the situation differently.
Set up some variables, for page and inner page with the default values and only re-assign them if the $_GET params are set
$page = 'home';
$inner_page = 'index.php';
if( isset( $_GET['p'] ) )
{
$page = htmlspecialchars( $_GET['p'] );
}
if( isset( $_GET['sp'] ) )
{
$inner_page = htmlspecialchars( $_GET['sp'] );
}
include $_SERVER['DOCUMENT_ROOT'] . '/Page/' . $page . '/' . $inner_page;
I've added $_SERVER['DOCUMENT_ROOT'] in too because if you use /Page then it is an absolute path, probably not what you were expecting, so prepending $_SERVER['DOCUMENT_ROOT'] ensures you're looking at the path inside your web directory.
Something else worth noting; Don't assume the data is good, people could try manipulate the files that are included.
http://your.domain/index.php?p=../../../../../&sp=passwd
So it would be worth trying to sanitize the data first.
Your current code has a big security flaw.
One of the most important rule when you write an app, never trust data coming from client. Always assume, they will send you wrong or bogus data.
I would recommend you to create a configuration file defining what are the allowed routes.
By executing the following line, you just allowed anyone to access any file that would be readable by your webserver.
include('/Page/' . htmlspecialchars($_GET["p"]) . '/' . htmlspecialchars($_GET["sp"]));
What happens If you sent a valid value for $_GET['p'] and this for $_GET['sp'] :
"/../../../../../../../../../../../etc/apache2/httpd.conf"
In this example, it will output your apache configuration file (assuming that this is the right path, if not an hacker can just keep trying path until he finds it).
To avoid this, you have two solutions.
1# Quick fix - You can sanitize & filter $_GET['p'] and $_GET['sp'] to ensure that you are not getting something '/../'. Make sure to add at least a file_exists before to avoid getting unwanted warning messages.
2# More elegant fix - You can create a configuration file that would contain the routes that you are accepting. If you are using a framework, there is a very high chance that you have a routing class or a routing module that you can just use. Otherwise, if you feel like implementing your own basic routing mechanism, you could do something as simple as in your case :
<?php
/**
* Defines the different routes for the web app
* #file : config.routes.php
*/
return array(
'page1' => array(
'index.php',
'subpage2.php',
'subpage3.php',
),
);
Then, your code you would check if the $_GET['p'] and $_GET['sp'] are allowed values or not.
<?php
// Load config file containing allowed routes
$allowedRoutes = require(__DIR__ . '/config.routes.php');
$defaultPage = 'home';
$defaultSubPage = 'index.php';
$page = isset($_GET['p']) ? $_GET['p'] : defaultPage;
$subPage = isset($_GET['sp']) ? $_GET['sp'] : $defaultSubPage;
// If it is an invalid route, then reset values to default
if (!isset($allowedRoutes[$page][$subPage]))
{
$page = $defaultPage;
$subPage = $defaultSubPage;
}
include $_SERVER['DOCUMENT_ROOT'] . '/Page/' . $page . '/' . $subPage;
How to pass an array from one file to another using include using PHP language?
I have one file with some language array(language/langen.php):
global $lang;
$lang['Here'] = 'Here';
$lang['Date'] = "Date";
In other file I have:
include base_url().'language/lang'.$_COOKIE['lang'].'.php';
var_dump($lang);
*(My mistake by coping code - true is var_dump($lang))*
But it shows me an error:
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: lang
How to solve this problem and what did I do wrong?
First of all:
You should never use cookie value directly in include statement - its pretty easy to make fake cookie and mess up in your application.
I suppose you just don't have cookie with name lang or variable $lang has never been initialized before.
To check if cookie exists and is in correct format you can do like that:
// set default lang code
$langCode = 'en';
// check if cookie exists and if contains string build from 2 characters from range a-z
// check also if file exists
if (isset($_COOKIE['lang'] && preg_match('/^[a-z]{2}$/', $_COOKIE['lang']) &&
file_exists(base_url().'language/lang'.$_COOKIE['lang'].'.php')) {
$langCode = $_COOKIE['lang'];
}
include base_url().'language/lang'.$langCode.'.php';
in included file you should check if variable $lang exists
if (!isset($lang)) $lang = array();
$lang['Here'] = 'Here';
$lang['Date'] = "Date";
also I think using global here is pointless as from your example it looks like its the same scope.
anyway for me much cleaner solution would be:
// first_file.php
$langCode = 'en';
if (isset($_COOKIE['lang'] && preg_match('/^[a-z]{2}$/', $_COOKIE['lang']) &&
file_exists(base_url().'language/lang'.$_COOKIE['lang'].'.php')) {
$langCode = $_COOKIE['lang'];
}
$lang = include base_url().'language/lang'.$langCode.'.php';
// langen.php
return array(
'Date' => 'Date',
'Here' => 'Here',
);
EDIT
One more thing - If base_url() is returning web URL (like http://example.com...) then it is also wrong (and also can cause problem as langen.php will contain at least Notice message when included this way) - should be included with valid file path
Shouldn't it be?
include base_url().'language/lang'.$_COOKIE['lang']['Here'].'.php';
Or else it would just return array()
First of all, I don't see the point of var-dumping variable $data, if there is no such thing in code you posted. If you have a cookie called "lang" in your browser, then you should be fine. You could always check this by
var_dump($GLOBALS['lang']);
in your code. It should print the array of values from your lang*.php file.
Sorry if the title is not enough clear, I didn't know how to write it better.
The situation is that I a have a cron job that sends mails to users. I have language files, and depending in the configuration of the user I want to send the mail in his language.
But I don't know how to do this.
Each language file have constants definitions like:
en.php define('DATE','Date'); define('TIME','Time');
es.php define('DATE','Fecha'); define('TIME','Hora');
And I need to display the correct labels depending the user language, but I'm in a while loop:
while ($row = mysql_fetch_array($res)) {
if ($row['lang'] == en) //load the english labels
}
So I think I can't use something like "include_once" in each iteration.
The problem is that you use PHP Constants for it so once they are set, you can't really change them within the script. Try to rewrite your constants and all references of them into variables.
Let's say that your language files are named like this lang.code.php and the script that will send the email is in sendemail.php. You can do something like this:
In lang.en.php
<?php
$terms['date'] = 'Date';
In lang.es.php
<?php
$terms['date'] = 'Fecha';
In sendemail.php:
<?php
function sendEmail($language = 'en')
{
include "lang.$language.php";
extract($terms);
$to = 'foo#bar.com';
$subject = 'Test';
$body = "The $date today is: " . date('r');
mail(...);
}
foreach($users as $user)
sendEmail($user->preferredLanguage);
You can then reference terms in your language files using their keys in the $terms array. Of course you'd have to create validation checks for the language files, directory traversals, etc. But that's one way to implement it.
If you can't rewrite your code then I suggest putting all of the email contents in one file and use file_get_contents() to fetch the email content via HTTP. Inside that file, you'd have a conditional which loads the language file you need.
Let's say that the file that will generate the email contents is called emailcontent.php, you can do something like this:
In lang.en.php
<?php
define('DATE', 'Date');
In lang.es.php
<?php
define('DATE, 'Fecha');
In emailcontent.php
<?php
require "lang.{$_GET['lang']}.php";
echo 'The ' . DATE . ' today is: ' . date('r');
In sendemail.php
<?php
$to = 'foo#bar.com';
$subject = 'Test';
foreach($users as $user)
{
$contents = file_get_contents('http://yourhost.com/emailcontent.php?lang=en');
mail(...);
}
Of course you need to add some security checks to prevent local file inclusion, access to emailcontent.php, etc. But this is the gist of it. However this has a big overhead in terms of latency and repeated compilation of your PHP code. If there was any other way to clear the global score for each email, then that is the better way to go. But this is the only way I can think of if you can't rewrite your code.
In this can I thing you should store the template to datebase its self, based on language you can fetch from DB
Or
Another way you have to get every variable conditional like
en.php define('DATE_EN','Date'); define('TIME','Time');
es.php define('DATE_FR','Fecha'); define('TIME','Hora');
if ($row['lang'] == en)
DATE_EN
else
DATE_FR
In your case constants will not work, since they cannot be changed during the execution.
Instead, I would recommend including all language information in one file, these can be constants each containing a different array:
langs.php
define('EN', array(
'DATE' => 'Date',
'TIME' => 'Time',
));
define('ES', array(
'DATE' => 'Fecha',
'TIME' => 'Hora',
));
Next, you can add a value to the array $row for each user, or you can use a variable like $lang which will be overwritten every while loop.
require_once 'langs.php' //or include_once
while ($row = mysql_fetch_array($res)) {
if ($row['lang'] == en) { //load the english labels
$lang = EN;
} elseif ($row['lang'] == es {
$lang = ES;
}
echo "Welcome {$row['name']}, today it's {$lang['DATE']}" //will display the corresponding $lang value
}