I have array, where i put data depend on the url. But there is the problem, i can not print this array like in the simple php:
$array = ["hi", "name"]; echo $array[1];
what is wrong in my code that i will show, and how i can print the array
Code:
<?php
class Translate {
public $transl = [];
public function getTransl($transl = []) {
if (( isset($_GET['lang']))) {
if ($_GET['lang'] == "en") {
$this->transl = ['word1', 'word2'];
}
if ($_GET['lang'] == "ru") {
$this->transl = ['word3', 'word4'];
}
}
}
}
$test = new Translate();
$test->getTransl([0]);
?>
No idea, why are you using $transl = [] in method parameter when you need specific index, here you can just pass key which you need.
Example:
<?
class Translate {
public $transl = 0;
public function getTransl($transl = '') {
if (( isset($_GET['lang']))) {
if ($_GET['lang'] == "en") {
$this->transl = ['word1', 'word2'];
}
if ($_GET['lang'] == "ru") {
$this->transl = ['word3', 'word4'];
}
}
return $this->transl[$transl];
}
}
$test = new Translate();
echo $test->getTransl(0); // this will print `word1` if $_GET['lang'] equal to `en`
?>
In your code, you are not using either echo or return in your method to get the result, and you are not matching $transl with $this->transl anywhere to get the specific index.
First, you don't pass the index as a parameter. You use it as an index. Proper syntax would be:
$test->getTransl()[0];
That assumes that $test->getTransl() returns an array. But it doesn't. It doesn't return anything. It just sets the class attribute $transl. So, you have to do it in two lines:
$test->getTransl(); // This sets the attribute
$test->transl[0]; // This uses the attribute
But, that goes against that the method implies. The method implies that it returns the transl attribute. So, you SHOULD return it in the function with:
return this->transl;
Then, you can use:
$test->getTransl()[0];
Of course, this won't print anything. You need to precede with with echo or print:
echo $test->getTransl()[0];
I think you'll just need to return the output.
Let's say you have a file named test.php on your server
class Translate {
public $transl = [];
public function getTransl($transl = []) {
if (( isset($_GET['lang']))) {
if ($_GET['lang'] == "en") {
$this->transl = ['word1', 'word2'];
}
if ($_GET['lang'] == "ru") {
$this->transl = ['word3', 'word4'];
}
}
return $this->transl;
}
}
$test = new Translate();
$output=$test->getTransl([0]);
echo "<pre>";
print_r($output);
echo "</pre>";
Running http://server/{{enterfolderhere}}/test.php?lang=en in your browser will give
Array
(
[0] => word1
[1] => word2
)
Running http://server/{{enterfolderhere}}/test.php?lang=ru in your browser will give
Array
(
[0] => word3
[1] => word4
)
There are a few issues with your code as others have pointed out. But from a code structure point of view, there are some more fundamental issues (IMHO).
If you are going to create a translator, basing it on if $_GET variables means it can be difficult to test. In this example, you send in a language you want in the constructor and then the class will just set the private translator variables to the table of translations.
Secondly - using numeric values for the word your after can be prone to errors (so can this method, but less so). In this case, the key of the translation is the word you want to start with and the value is the new word, so rather than
echo $test->getTransl(0);
you use
echo $russianTrans->getTransl("word2");
This is the code, hope it helps...
class Translate {
// Use private variables whenever possible
private $transl = [];
public function __construct( string $lang ) {
if ($lang == "en") {
$this->transl = ['word1' => 'word1', 'word2' => 'word2'];
}
if ($lang == "ru") {
$this->transl = ['word1' => 'word3', 'word2' => 'word4'];
}
}
public function getTransl($word) {
return $this->transl[$word];
}
}
$russianTrans = new Translate($_GET['lang']); // Or hardcode it to 'ru' for example
echo $russianTrans->getTransl("word2");
Related
I have an array like this...
[Summary] => Array
(
[0] => yearManufactured
[1] => &&
[2] => make
[3] => ||
[4] => model
)
how can I convert this array into function calls and operators and then use it to make a comparision, for example turn it into this...
if( $this->yearManufactured() && $this->make() || $this->model() ) {
// do something
} else {
// do something else
}
Methods in class..
public function yearManufactured() {
return true;
}
public function make() {
return false;
}
public function model() {
return true;
}
This seems like something that could actually be a valid use for eval. You can verify that each array item is either an operator or a valid method name, and convert the result of the method call to a boolean string. Putting those things together should result in a string that you can safely eval without worrying about it doing something nasty, other than maybe causing a parse error, which can be caught in PHP 7.
If you find anything in the array that isn't supposed to be there, or the expression doesn't parse, you can return null, or throw an exception, however you want to handle it.
public function evaluateExpressionArray(array $expression) {
// build the expression
$expr = '$result =';
foreach ($expression as $part) {
if ($part == '||' || $part == '&&') {
$expr .= " $part ";
} elseif (method_exists($this, $part)) {
$expr .= $this->$part() ? 'true' : 'false';
} else {
return null;
}
}
// try to evaluate it
try {
eval("$expr;");
} catch (ParseError $e) {
return null;
}
return $result;
}
Be very careful with eval, though. Don't ever put anything into it unless you know exactly what it is.
Here's an example to mess with.
I have one PHP class as below (part of the code):
class myclass{
private static $arrX = array();
private function is_val_exists($needle, $haystack) {
if(in_array($needle, $haystack)) {
return true;
}
foreach($haystack as $element) {
if(is_array($element) && $this->is_val_exists($needle, $element))
return true;
}
return false;
}
//the $anInput is a string e.g. Michael,18
public function doProcess($anInput){
$det = explode(",", $anInput);
if( $this->is_val_exists( $det[0], $this->returnProcess() ) ){
//update age of Michael
}
else{
array_push(self::$arrX, array(
'name' => $det[0],
'age' => $det[1]
));
}
}
public function returnProcess(){
return self::$arrX;
}
}
The calling code in index.php
$msg = 'Michael,18';
myclass::getHandle()->doProcess($msg);
In my webpage says index.php, it calls function doProcess() over and over again. When the function is called, string is passed and stored in an array. In the next call, if let's say same name is passed again, I want to update his age. My problem is I don't know how to check if the array $arrX contains the name. From my own finding, the array seems to be re-initiated (back to zero element) when the code is called. My code never does the update and always go to the array_push part. Hope somebody can give some thoughts on this. Thank you.
There is a ) missing in your else condition of your doProcess() function, it should read:
else{
array_push(self::$arrX, array(
'name' => $det[0],
'age' => $det[1]
)); // <-- there was the missing )
}
Here is a complete running solution based on your code:
<?php
class myclass{
private static $arrX = array();
private function is_val_exists($needle, $haystack) {
if(in_array($needle, $haystack)) {
return true;
}
foreach($haystack as $element) {
if(is_array($element) && $this->is_val_exists($needle, $element))
return true;
}
return false;
}
//the $anInput is a string e.g. Michael,18
public function doProcess($anInput){
$det = explode(",", $anInput);
if( $this->is_val_exists( $det[0], $this->returnProcess() ) ){
//update age of Michael
for ($i=0; $i<count(self::$arrX); $i++) {
if (is_array(self::$arrX[$i]) && self::$arrX[$i]['name'] == $det[0]) {
self::$arrX[$i]['age'] = $det[1];
break;
}
}
} else{
array_push(self::$arrX, array(
'name' => $det[0],
'age' => $det[1]
));
}
}
public function returnProcess(){
return self::$arrX;
}
}
$mc = new myclass();
$mc->doProcess('Michael,18');
$mc->doProcess('John,23');
$mc->doProcess('Michael,19');
$mc->doProcess('John,25');
print_r($mc->returnProcess());
?>
You can test it here: PHP Runnable
As I said in comments, it looks like you want to maintain state between requests. You can't use pure PHP to do that, you should use an external storage solution instead. If it's available, try Redis, it has what you need and is quite simple to use. Or, if you're familiar with SQL, you could go with MySQL for example.
On a side note, you should read more about how PHP arrays work.
Instead of array_push, you could have just used self::$arrX[] = ...
Instead of that, you could have used an associative array, e.g. self::$arrX[$det[0]] = $det[1];, that would make lookup much easier (array_key_exists etc.)
Can you try updating the is_val_exists as follows:
private function is_val_exists($needle, $haystack) {
foreach($haystack as $element) {
if ($element['name'] == $needle) {
return true;
}
return false;
}
First of all sorry for the title, but i had no clue how i should name it.
Let's say i have it like that:
$lang = new lang;
$lang->setLanguage('en');
$string = $lang->get('Willkommen');
This would output Welcome for example.
But what i want is this:
$lang = new lang;
$lang->setLanguage->en
$string = $lang->get->Willkommen
As you thought, this should also output Welcome.
In order words, i want the same result, but without having to pass arguments to the instance.
I searched a long time now, but could not find out how i could do that.
Sounds like you're looking for the __get magic method.
class lang {
var $language = 'en';
function __get($prop) {
if ($prop == 'Willkommen') {
if ($this->language == 'en') return 'Welcome';
else if ($this->language == 'fr') return 'Bonjour';
}
}
function __set($prop, $val) {
if ($prop == 'language') $this->language = $val;
}
}
$lang = new lang();
echo $lang->Willkommen; // Prints "Welcome"
$lang->language = 'fr';
echo $lang->Willkommen; // Prints "Bonjour"
In php, dynamic access is with {} :
$key = 'Willkommen';
$lang->{$key};
//first function
function insertdigit(){
$userdigit=5;
$flag = $this->usermodel->userdigitmodel($userdigit);
$value = array(
'result' => $flag
);
echo json_encode($value);
if ($flag == true) {
return $userdigit;
} else {
}
}
//second function
function usedigit(){
$data['userdigit']=$this->insertdigit();
}
but i get {"result":true} goes back to the function? how to access a member variable in a different member function
Try to remove echo json_encode($value); in your code.
If you need to access a parameter in several functions on your controller, you have to create it outside your function so it will be available for all your controller functions.
So, in your case it should be something like this:
class Test extends Controller
{
private $userdigit; //here you can set a default value if necessary: private $userdigit = 5
function insertdigit(){
$this->userdigit=5;
$flag = $this->usermodel->userdigitmodel($this->userdigit);
$value = array(
'result' => $flag
);
echo json_encode($value);
if ($flag == true) {
return $this->userdigit;
} else {
}
}
//second function
function usedigit(){
$data['userdigit']=$this->userdigit;
}
}
This way your userdigit variable is available for all your functions. With $this you are telling PHP that you are trying to access something inside the class.
This link contain more and useful information: http://www.php.net/manual/en/language.oop5.properties.php
Is that what you really need?
A possible solution:
function insertdigit()
{
$userDigit = 5;
$flag = $this->usermodel->userdigitmodel($userDigit);
$value = array
(
'result' => $flag
);
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
{
echo json_encode($value);
}
if ($flag == true)
{
return $userdigit;
}
else
{
}
}
//second function
function usedigit()
{
$data['userdigit'] = $this->insertdigit();
}
The above code, in insertdigit detects if there is an Ajax request and if so, it will echo out the json_encoded data. If you call it in an normal request, i.e. via usedigit it won't echo the json_encoded data (unless you are calling usedigit via an Ajax request).
Your question doesn't really explain what you are doing, so it's hard to explain a better solution, however, if you are trying to access a "variable" in more than one place, you should really separate your code so you have a single entry point for that variable.
Is your variable dynamic, or is it static?
I'm parsing the HTTP_ACCEPT_LANGUAGE header to get users' language and I'm building a class to do that.
Actually I build an associative array ("$this->user_lang") where keys are the language (such as "en-us", "it-it", "it-ch" etc) and the value is the quality factor (so I can order languages).
Then I have another associative array named "$this->installed_langs" where I declare supported language and locales (in the form "en" => "en_US", "it" => "it_IT").
All I want to do is try to match one of the key of "$this->user_lang" with one of the "$this->installed_langs" (without care of the local zone after the "-") and return the first occurrence (with no care for other matching case).
I ended up with this method but it seems a bit too complex...
public function show() {
$g_locale = null;
foreach ($this->user_lang as $lang => $q) {
foreach($this->installed_langs as $valid => $locale) {
if (strpos($lang, $valid) !== false) {
if ($g_locale === null) $g_locale = $locale;
}
}
}
// debug:
echo $g_locale;
}
I hope I have explained it well, btw if you need more informations, please, ask me.
Try this
public function show() {
$g_locale = null;
foreach ($this->user_lang as $lang => $q) {
if ( array_key_exists( $lang, $this->installed_langs ) ) {
$g_locale = $this->installed_langs[$lang];
}
}
}
function show() {
$g_locale = null;
foreach ($this->user_lang as $lang => $q) {
$_key=explode($lang, '-'); // 'en-us' => 'array('en', 'us')
$key=$_key[0]; // 'en'
if ( array_key_exists( $key, $this->installed_langs ) ) {
$g_locale = $this->installed_langs[$key];
}
}
}