What I would like is to store every word / sentence / ... in a database tabel like so:
Table name:
translate
columns:
id, var, dutch, english, french
Example:
'1', 'titleOne', 'Hallo Wereld!', 'Hello World!', 'Bonjour le monde!'
What I would like is to print the variable for example at the title section:
<?php
echo $titleOne;
?>
Since there will be hundreds of lines I do not want to set $titleOne = $row['titleOne'] for every line.
Can someone please help me out with a nice query, pull, fetch, array, loop, ... however you call this? (or a nice alternative way is also good!)
This is plain PHP, no frameworks are used.
PS: I am not a PHP expert at all so please try to keep it simple :-)!
Thanks a lot!
I 2nd the advice given by others about your table structure, but to answer your question you can use extract
$row = array(
col_1 => 'a',
col_2 => 'b',
col_3 => 'c'
)
extract($row);
// results in:
// $col_1 assigned value 'a'
// $col_2 assigned value 'b'
// $col_3 assigned value 'c'
To answer your question directly. You could query your current setup as follows:
-- For Dutch (pseudocode)
$query = 'SELECT var, dutch FROM translate';
$translations = array();
while loop ($row = $query) {
$translations['var'] = $row['dutch'];
}
// Then, to access translations you would:
echo $translations['titleOne'];
BUT you don't want to do this. This table structure will lead you down a path of regret. Heed our warnings. There are many ways to go about this and you've chosen to go the SQL route so here are some tips.
Change your table structure so you don't have to add a new column each time you add a new language.
Table: languages (Add a new row to support a new language)
id, locale, language
1, en_CA, English
2, en_US, English
3, en_UK, English
4, es_ES, Spanish
5, es_MX, Spanish
...
Table: translations (add a new row to add a translation)
id, locale, translation_key, translation
1, en_CA, 'hello', 'Hi from Canada'
2, en_US, 'hello', 'Hi from the US'
3, en_UK, 'hello', 'Hi from the UK'
4, es_ES, 'hello', 'Hi from Spain'
5, es_MX, 'hello', 'Hi from Mexico'
...
translations.locale should be a foreign key pointing back to languages but I'm not sure what your SQL level is so leaving it as clear as I know how.
I assume you can figure out how to query your database from PHP. What you want to do is:
figure out which locale to use. This will be one of the trickiest parts. Ex. should you be using the one specified in the URL, the session, the browser setting? What happens if none of those is specified? What is the fallback locale? See my getLanguage() function in https://stackoverflow.com/a/49758067/296555 for some ideas.
Pull all translations for that locale and store them in memory. Here is a basic query to pull all translations for a given locale.
<?pseudocode
$locale = 'en_CA';
// Find all translations for a given locale
$dbQuery = 'SELECT translation_key, translation
FROM translations
WHERE locale = :locale';
;
Put those entries you just pulled in to memory.
<?pseudocode
$translations = array();
while loop ($row = $dbQuery) {
$translations[$row['translation_key']] = $row['translation'];
}
Throughout your application, you can now access translations via that array.
echo $translations['hello'];
You'll want to do this high up in your application in a part that is called on every request. Once you have this going you will want to start optimizing. You could store the database results to the session so you don't have to query the DB on each page load or implement a more robust form of caching.
In all honesty, I think you have the right idea but the devil is in the details or so they say. Read the link that I pointed to. It isn't perfect but it should help you get to a workable solution relatively quickly.
Related
Hello im building a multilenguaje app in php, this is the first time i handle multilenguaje, im trying to do it like this.
For months for example
i have a table "months" with id | month estructure
in the users table i have id | username | month_id
my guess (bad guess) its that i can save for example $january direct on the database so in the php when its called, it looked for the defined variable.
$january = "january"; and if im on spanish web then i change this to $january = "Enero";
but this is not working (obviusly because it prints as a result of a call $january, Its saved as $january in the database)
How is the best method for what im trying to do.. cause im lost in this point.. and i need this estructure in the database for a lot of reasons i wont mention, right now,
thanks!
My code
This $row2['months']
Print this $january
Even when in the php code i have set $january = "enero";
You might rethink your strategy.
Example:
For 10 languages if you keep 10 php files defining the month names or actually all language locale words in, it will be sufficient and you can include them without disturbing the database.
<?php
// this is words_en.php, you can make another like words_de.php etc.
$months = array('january','february','march','april'....etc );
?>
If you structure your locale file consistently for instance:
$msgs = array(
'MSG1'=>'first message',...
}
keeping only the references(like'MSG1') in your code and also in your database will be sufficient. For the months, you can keep them apart from $msgs since their use is specific and numeric indexing adds more consistency to coding for their case.
Note that this is not the only method for language locales but this is an easy to maintain version.
You should save the users locale e.g. en_US in your table and base further translations on that value with a fallback to the default language.
To get php to evaluate that variable, what you need to do is eval:
$january='Enero';
$row='$january';
echo $row; //Prints $january
echo PHP_EOL;
echo eval("return ".$row.";"); //Prints Enero
Here that is in ideOne: http://ideone.com/f0LCT0
Hello fellow StackOverflowers,
As modifications on my website were needed in result of massive growth and suggestions from the public, I needed to modify my database, which I have already done to adjust it to the visitor suggestions. Right, very confusing so I'll just get to the point:
Current query:
$arow=mysql_fetch_assoc(mysql_query("SELECT * FROM animelist WHERE id = '".$_REQUEST['id']."'"));
$placeholders = array(' ', ',', ':');
$replacements = array('-', '', '');
$title=str_replace($placeholders, $replacements,$arow['name']);
$title=preg_replace("/[^a-zA-Z0-9\s-]/", "", $title);
$link=$title."-".$arow['id'];
$link="Stream-".$title."-Episode-".$row1['episodes_id']."-".$row1['language']."-".$row1['id'];
Initially the part -Episode- was only needed to be named/written as '-Episode-', however to user suggestions and I completely agree, it needs to be dynamic aswell. Lets say (using the terms for reference only) at first the website only had Episodes and not Movies, but now also has Movies. So we want this part to be dynamic aswell. For this we use database information, I have made a column 'type' INT(1) in the table 'items' I suggest 0 to be -Episode- and if value under type is 1 then I suggest it to be -Movie-.
Now the question is how do I correctly implement it in the query? I understand more queries need to be made similar to the one from $title or $row1. this is what I have so far, but it is not complete yet, because I don't know how to:
$link="Stream-".$title."-.$type.-".$row1['episodes_id']."-".$row1['language']."-".$row1['id'];
$type=$arow['type']
Now there should be a code, which I am not sure of how to write correctly, which makes the condition that if type = 0 then echo Episode, elseif type = 1 then echo Movie.
I greatly appreciate the time you took to read this through and hope you can help me out.
Edit:
Assume $row1, is fetched from table named 'videos' and not from 'animelist', however the table 'videos' each video has an 'id' but also has an column named 'anime_id', this anime_id is equal to the 'id' in 'animelist', in short videos id is the post, and anime_id is the category.
More queries need to be written now to balance the game, please help me out, I am stuck.
Thanks in advance,
Inder
$type = ($arow['type']==0) ? "Episode" : "Movie";
or
$type = $arow['type'] ? "Episode" : "Movie";
I'm just learning PHP and I've searched for a while on this, but I'm afraid I may not know exactly how to ask it, so an explanation will probably work best. Basically I have a group by/count query returning 3 records.
Status Total
0 2
1 3
2 2
On my page I would like to display:
Status Total
Dev 2
Active 3
Arch 2
So I basically just want to assign the values 0, 1 and 2 to a text value. I've tried creating an array, then assigning the return number field equal to the array.
$_status = array(0 => 'Development', 1 => 'Production', 2 => 'Archive');
while($rowStat = mysql_fetch_assoc($resDev))
{
echo "<tr><td>$_status[$rowStat['status']]</td><td>{$rowStat['devprojects']}</td></tr>";
};
Any help is much appreciated.
Thanks.
as you can see here http://php.net/mysql_fetch_assoc the field names are case sensitive
from what I see in your table sample the field is called "Status"
and you are using "status"
you can try changing
$rowStat['status']
to
$rowStat['Status']
Edit:
the initial version of the answer only focused on what's the problem (and suggested pdo)
I only want to add that I agree to two other optinions found here:
the one added via comment to this answer by giorgio: you should only use lowercase names for your database fields; also you should consider using the table name as a prefix (product_id instead or id, user_password instead of password) for two main reasons: to avoid colisions when you fetch results using a join and to avoit collisions with mysql reserved words (as id, password and status are)
the other one, suggested by Crashspeeder by a comment to the question: you definitely should develop with error reporting on and disable it on live servers
I don't really like using the 0, 1, 2 to represent a named value (unless you have a relational) table in your DB... but using your setup, why not just use:
while($rowStat = mysql_fetch_assoc($resDev)){
switch($rowStat['Status']){
case 0:
echo "<tr><td>Development</td><td>{$rowStat['devprojects']}</td></tr>";
break;
case 1:
echo "<tr><td>Production</td><td>{$rowStat['devprojects']}</td></tr>";
break;
case 2:
echo "<tr><td>Archive</td><td>{$rowStat['devprojects']}</td></tr>";
break;
}
};
EDIT
Some people really are looking for copy-paste answers so here's an updated answer because Sgt. Crashspeeder of the Massively Anal Society got her knickers in a twist.
Create a lookup array to reference against the status Ids:
$statusArray[0] = 'Development;
$statusArray[1] = 'Production;
$statusArray[2] = 'Archive;
Then when you're running your mysql_fetch_assoc() loop, you can reference the statusArray lookup like so:
while($rowStat = mysql_fetch_assoc($resDev)){
echo "<tr><td>{$statusArray[$rowStat['Status']]}</td><td>{$rowStat['devprojects']}</td></tr>";
}
I'm new to web design, especially backend design so I have a few questions about implementing a search function in PHP. I already set up a MySQL connection but I don't know how to access specific rows in the MySQL table. Also is the similar text function implemented correctly considering I want to return results that are nearly the same as the search term? Right now, I can only return results that are the exact same or it gives "no result." For example, if I search "tex" it would return results containing "text"? I realize that there are a lot of mistakes in my coding and logic, so please help if possible. Event is the name of the row I am trying to access.
$input = $_POST["searchevent"];
while ($events = mysql_fetch_row($Event)) {
$eventname = $events[1];
$eventid = $events[0];
$diff = similar_text($input, $event, $hold)
if ($hold == '100') {
echo $eventname;
break;
else
echo "no result";
}
Thank you.
I've noticed some of the comments mentioned more efficient ways of performing the search than with the "similar text" function, if I were to use the LIKE function, how would it be implemented?
A couple of different ways of doing this:
The faster one (performance wise) is:
select * FROM Table where keyword LIKE '%value%'
The trick in this one is the placement of the % which is a wildcard, saying either search everything that ends or begins with this value.
A more flexible but (slightly) slower one could be the REGEXP function:
Select * FROM Table WHERE keyword REGEXP 'value'
This is using the power of regular expressions, so you could get as elaborate as you wanted with it. However, leaving as above gives you a "poor man's Google" of sorts, allowing the search to be bits and pieces of overall fields.
The sticky part comes in if you're trying to search names. For example, either would find the name "smith" if you searched SMI. However, neither would find "Jon Smith" if there was a first and last name field separated. So, you'd have to do some concatenation for the search to find either Jon OR Smith OR Jon Smith OR Smith, Jon. It can really snowball from there.
Of course, if you're doing some sort of advanced search, you'll have to condition your query accordingly. So, for instance, if you wanted to search first, last, address, then your query would have to test for each:
SELECT * FROM table WHERE first LIKE '%value%' OR last LIKE '%value%' OR address LIKE '%value'
Look at below example :
$word2compare = "stupid";
$words = array(
'stupid',
'stu and pid',
'hello',
'foobar',
'stpid',
'upid',
'stuuupid',
'sstuuupiiid',
);
while(list($id, $str) = each($words)){
similar_text($str, $word2compare, $percent);
if($percent > 90) // Change percentage value to 80,70,60 and see changes
print "Comparing '$word2compare' with '$str': ";
}
You can check with $percent parameter for how strong match you want to apply.
I would like to create an advanced search form much like a job site would have one that would include criteria such as keyword, job type, min pay, max pay, category,sub category etc...
My problem is deciding on how best to set this up so if I have to add categories to the parameters I'm not having to modify a whole bunch of queries and functions etc...
My best guess would be to create some sort of associative array out of all of the potential parameters and reuse this array but for some reason I feel like it's a lot more complex than this. I am using CodeIgniter as an MVC framework if that makes any difference.
Does anybody have a suggestion as how best to set this up?
Keep in mind I will need to be generating links such as index.php?keyword=designer&job_type=2&min_pay=20&max_pay=30
I hope my question is not to vague.
I don't know if it's what you need, but I usually create some search class.
<?php
$search = new Search('people');
$search->minPay(1000);
$search->maxPay(4000);
$search->jobType('IT');
$results = $search->execute();
foreach ($results as $result)
{
//whatever you want
}
?>
You can have all this methods, or have some mapping at __set() between method name and database field. The parameter passed to the constructor is the table where to do the main query. On the methods or mapping in the __set(), you have to take care of any needed join and the fields to join on.
There are much more 'enterprise-level' ways of doing this, but for a small site this should be OK. There are lots more ActiveRecord methods you can use as necessary. CI will chain them for you to make an efficient SQL request.
if($this->input->get('min_pay')) {
$this->db->where('min_pay <', $this->input->get('min_pay'));
}
if($this->input->get('keyword')) {
$this->db->like($this->input->get('keyword'));
}
$query = $this->db->get('table_name');
foreach ($query->result() as $row) {
echo $row->title;
}
To use Search criterias in a nice way you should use Classes and Interfaces.
Let's say for example you define a ICriteria interface. Then you have different subtypes (implementations) of Criteria, TimeCriteria, DateCriteria, listCriteria, TextSearch Criteria, IntRange Criteria, etc.
What your Criteria Interface should provide is some getter and setter for each criteria, you'll have to handle 3 usages for each criteria:
how to show them
how to fill the query with the results
how to save them (in session or database) for later usage
When showing a criteria you will need:
a label
a list of available operators (in, not in, =, >, >=, <, <=, contains, does not contains) -- and each subtypes can decide which part of this list is implemented
an entry zone (a list, a text input, a date input, etc)
Your main code will only handle ICriteria elements, ask them to build themselves, show them, give them user inputs, ask them to be saved or loop on them to add SQL criteria on a sql query based on their current values.
Some of the Criteria implementations will inherits others, some will only have to define the list of operators available, some will extends simple behaviors to add rich UI (let's say that some Date elements should provide a list like 'in the last day', 'in the last week', 'in the last year', 'custom range').
It can be a very good idea to handle the SQL query as an object and not only a string, the way Zend_Db_Select works for example. As each Criteria will add his part on the final query, and some of them could be adding leftJoins or complex query parts.
Search queries can be a pain sometimes, but not as big of a pain as pagination. Luckily, CodeIgniter helps you out a bit with this with their pagination library.
I think you're on the right track. The basic gist, I would say, is:
Grab your GET variables from the URL.
Create your database query (sanitize the GET values).
Generate the results set.
Do pagination.
Now, CodeIgniter destroys the GET variable by default, so make sure you enable http query strings in your config file.
Good luck!
I don't know anything about CodeIgniter, but for the search application I used to support, we had drop-down combo-boxes with category options stored in a database table and would rely on application and database cacheing to avoid round-trips each time the page was displayed (an opportunity for learning in itself ;-). When you update the table of job_type, location, etc. the new values will be displayed in your combo-box.
It depends on
how many categories you intend to have drop-down lists
how often you anticipate having to update the list
how dynamic you need it to be.
And the size of your web-site and overall activity are factors you will have to consider.
I hope this helps.
P.S. as you appear to be a new user, if you get an answer that helps you please remember to mark it as accepted, or give it a + (or -) as a useful answer
A pagination class is a good foundation. Begin by collecting query string variables.
<?php
// ...in Pagination class
$acceptableVars = array('page', 'delete', 'edit', 'sessionId', 'next', 'etc.');
foreach($_GET as $key => $value) {
if(in_array($key, $acceptableVar)) {
$queryStringVars[] = $key . '=' . $value;
}
}
$queryString = '?' . implode('&', $queryStringVars);
$this->nextLink = $_SEVER['filename'] . $queryString;
?>
Duplicate the searchable information into another table. Convert sets of data into columns having two values only like : a search for color=white OR red can become a search on 10 columns in a table each containing one color with value 1 or 0. The results can be grouped after so you get counters for each search filter.
Convert texts to full text searches and use MATCH and many indexes on this search table. Eventually combine text columns into one searchable column. The results of a seach will be IDs which you can then convert into the records with IN() condition in SQL
Agile Toolkit allows to add filters in the following way (just to do a side-by-side comparison with CodeIgniter, perhaps you can take some concepts over):
$g=$this->add('Grid');
$g->addColumn('text','name');
$g->addColumn('text','surname');
$g->setSource('user');
$conditions=array_intersect($_GET, array_flip(
array('keyword','job_type','min_pay'));
$g->dq->where($conditions);
$g->dq is a dynamic query, where() escapes values passed from the $_GET, so it's safe to use. The rest, pagination, column display, connectivity with MVC is up to the framework.
function maybeQuote($v){
return is_numeric($v) ?: "'$v'";
}
function makePair($kv){
+-- 7 lines: $a = explode('=', $kv);
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
}
function makeSql($get_string, $table){
+-- 10 lines: $data = explode('&', $get_string);
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
}
$test = 'lloyd=alive&age=40&weather=hot';
$table = 'foo';
print_r(makeSql($test, $table));