I have a database table containing some Permanent Texts which I will be outputting to my user interactions. The problem is that I need to change some parts of these Permanent Text answers when querying the Database.
For example this is one of the responses I will be giving to the user:
I'm sorry, your answer is wrong. The correct answer is "ANSWER". Don't demoralize yourself and keep training!
But as you see the ANSWER should be the number or text I would like to replace during the query so I get the correct result, as an example result:
I'm sorry, your answer is wrong. The correct answer is "Option 1". Don't demoralize yourself and keep training!
I am doing these queries inside CodeIgniter (PHP Framework) and this is the style of code I'm using:
public function mo_response_content($mo_response_content_id)
{
$this->db->select('*');
$this->db->where('id', $mo_response_content_id);
// Code to add for replacing part of the result
$query = $this->db->get('actions_mo_contents');
$row = $query->row();
if ($row)
{
return $row;
} else
{
return NULL;
}
}
How can I replace the ANSWER string during the database query?
Use the MySQL REPLACE() function as the following:
$this->db->select("*, REPLACE(string_column, 'ANSWER', 'replaceTextHere') AS 'response'");
Related
So my controller looks like this:
public function insert(){
//form_validation_rules
if($this->form_validation->run() == FALSE){
//redirect to view
}else{
//get data here $this->input->post()
//insert into table here all others depend on this table to exist
//returns story_id
if($table_id){
// here i have to insert data into 4 more table.
}
}
}
My erd looks like this:
So i have to insert into story table first since the story has to exist before i insert the genre/tags/content warning and finally the chapter since in my form to create a new story you have to add the first chapter too.
An answer to my previous question told me a nested if is bad practice and ive also searched here and saw this: PHP - Nested IF statements
My confusion is, where do i process and insert my data if i were to follow a scheme like that?
Writing this question up to here, my brain cleared up a bit, so i might aswell ask if i am right or in the right direction.
So i'll do it like this:
//process data here
$insert_genre = $this->model->insert_genre($genre);
$insert_tag = $this->model->insert_tags($tags);
$insert_warning = $this->model->insert_warning($content_warning);
$insert_chapter = $this->model->add_chapter($chapter);
if(!insert genre){
//redirect view }
if(!insert tags){
//redirect view }
if(!insert content_warning){
//redirect view }
if(!insert chapter){
//redirect view }
else{
//load view
}
EDIT:
This is how my model method for inserting genre/tag/contentwarning looks: theyre all similarly written.
public function new_story_genre($genre){
$inserted = 0;
foreach($genre as $row){
$this->db->insert('story_genre', $row);
$inserted += $this->db->affected_rows();}
if($inserted == count($genre)){
return TRUE;}else{ return FALSE; }
}
Nested if conditions are perfectly acceptable if they are not too many and if it is still easy to read.
You could easily nest your ifs here.
Personally i would use one if in this case:
// if insert errors: redirect view
if(!$insert_genre || !$insert_tags || !$insert_warning || !insert_chapter){
// redirect view
}
Pro tip: indent everything correctly, it helps wonders with readability of your code.
Edit:
you mentioned error strings in comments. Here is how you could structure your ifs with custom error strings:
if(!$insert_genre = $this->model->insert_genre($genre)){
redirect_view("Genre insert failed!");
}
if(!$insert_tags = $this->model->insert_tags($tags)){
redirect_view("Tags insert failed!");
}
public function redirect_view($errorString = ""){
// redirect view with individual error string
}
if you want you can also return an error string in the insert functions of the model. you have to change this code of the controller a bit but it would definately possible.
I've got this code:
function searchMovie($query)
{
$this->db->where("film_name LIKE '%$query%'");
$movies = $this->db->get ("films", 40);
if($this->db->count > 0)
{
return $movies;
}
return false;
}
Javascript code from my submit form button strips all special characters like ; : ' / etc. from query string, and then redirects user to search uri (szukaj/query). So for example if film_name is Raj: wiara, and user searches for raj: wiara, the query looks like raj wiara and user doesn't get any results. I was thinking about exploding query into single words and then foreach word do a SELECT from db, but it would give multiple results of same movie. Don't want to change the javascript code, and I think I can't make that film names without the special characters like :.
Or maybe create another column in db for film_keywords and add there all words of movie separated by , or something and then search this column?
MySQL's Full Text Search functions are your friend here:
http://dev.mysql.com/doc/refman/5.7/en/fulltext-search.html
Will return a series of matches and give a score so you return in best-match order.
Warning: $this->db->where("film_name LIKE '%$query%'"); is open to SQL injection. Anyone can circumnavigate the JavaScript so you must always clean up input server-side. This is best done using the DB functions as well, not just stripping characters - so check whatever library you are using in order to do this.
You could indeed explode your string, using this answer's solution.
function searchMovie($query)
{
$queries = preg_split('/[^a-z0-9.\']+/i', $query);
foreach ($queries as $keyword){
$this->db->where("film_name LIKE '%$keyword%'");
}
$movies = $this->db->get ("films", 40);
if($this->db->count > 0)
{
return $movies;
}
return false;
}
This will create multiple ANDconditions for your db where, so the result will be filtered.
i want to replace a string with database function if it exists. i am using str_replace in following way but it doesn't work for me, this is returning $numOne as it was. i am beginner in php so help me
function stringreplace($multiple,$numOne){
$multiple=Multiply;
$numOne=a_b_cMultiply;
str_replace($multiple,"abcdfgh('','')::numeric",$numOne);
return $numOne;
}
Your code is not correct as you are not storing the result anywhere and also you are returning $numOne which contains the old value . Use this code:
function stringreplace($multiple,$numOne){
$multiple='Multiply';
$numOne='a_b_cMultiply';
$num_one = str_replace($multiple,"abcdfgh('','')::numeric",$numOne);
return $num_one;
}
I'm working on building a social network from HTML, PHP, and a MySQL database, and I cant figure how to make this PHP code to work. Please remember, I'm totally not a pro at PHP.
What I'm working on now is a function, atreplace($text), that has the preg_replace() function in it to find the # mentions in a post caption, comment, or wherever else I use it, to make them into clickable links. Now that's pretty easy, except the #mentions in the strings it would process are user id numbers instead of the user name. For example, a string in a post caption for my social network would look like this:
"Went to Disneyland with my friends #214432 and #163728 today.". But what the post caption originally said was this: "Went to Disneyland with my friends #billysmith and #hi_im_kelly today.".
I wrote the script (not included because it doesn't have to do with the question) that processes the post data and inserts it into the MySQL database to replace the # mentions to be the user number id of the user that was mentioned instead of the user name in situations where people would have changed their username, then it wouldn't have to edit peoples posts where they mentioned someone that changed their username.
Problem
When it uses the atreplace() function to echo out the post caption when someone is viewing their feed, of course it will echo out "#214432" and "#163728" (from the example above) in the post caption instead of "#billysmith" and "#hi_im_kelly", which I would expect, because a different php script edited it and changed the usernames that were mentioned to be the user id, which is a number.
This is what I want
I want to write a function like the one I have below (get_username($id)). I only included get_username($id) to show what I want to do. I dont really know a lot about how to use the preg_replace() function yet.
As you can see, I tried passing the $1, which would be the user number id that I want it to replace with the username, with the get_username('$1) function, but it doesn't work. (I know I used that $1 wrong somehow). Although in the get_username() function, when I try returning the $id, it does output the user number id right. But when I used the $id in the mysql_query(), it didn't even show up.
In case you didn't understand all that, first, I want to put the string that has the # mentions in it, into the atreplace() function. This function will find all the # user mentions, remember, they are the users number id. Then, it will put each mention into the get_username() function. That function will get the username from a mysql database where the id equals the user number id that the atreplace() function found, then it will return the username, and in the end, will replace the # mention...
Can someone please show me how I could change the get_username() function to make it work? Or just write a new one.
<?php
function get_username($id){
$undata = mysql_query("select `username` from `accounts` where `id`='$id';");
$un = mysql_fetch_assoc($undata);
return "<a href='#'>#".$un['username']."</a>";
}
function atreplace($text){
$replaced = preg_replace('/\#(\w+)/', get_username('$1'), $text);
return($replaced);
}
?>
regarding mysql_* being deprecated and using prepared statements along with preg_replace_callback:
$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'localonly', 'localonly', array(
PDO::ATTR_EMULATE_PREPARES=>false,
PDO::MYSQL_ATTR_DIRECT_QUERY=>false,
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION
));
...
function atreplace($text, $pdo) {
$stmt = $pdo->prepare('
SELECT
`username`
FROM
`so_profiles`
WHERE
`id`=?
');
$mesg = preg_replace_callback(
'/\#(\w+)/',
function ($match) use($stmt) {
$stmt->execute( array($match[1]) );
$users = $stmt->fetchAll(); // yes, there should be only one....
return empty($users) ? '[unknown user]' : $users[0];
},
$text
);
return $mesg;
}
In case anyone ever has that same problem, I got the answer thanks to #VolkerK
I just changed it to be one function:
function atreplace($text){
$mesg = preg_replace_callback('/\#(\w+)/',
function ($match){
$matchedit = preg_replace('/\#(\w+)/','$1', $match[0]);
$und = mysql_query("select `username` from `so_profiles` where `id`='".$matchedit."';");
$un = mysql_fetch_array($und);
return "<a>#".$un['username']."</a>";
},
$text);
return($mesg);
}
I have a function (which I did not write) inside an existing php tag in the head of a page that I've been using for several years the parses URL's and email addresses to make them clickable links:
function ParseURLs($str){
if(isset($str)){
$Output=strip_tags($str);
$Output=preg_replace("/(\swww\.)|(^www\.)/i"," http://www.",$Output);
$Output=preg_replace("/\b(((ftp|http(s?)):\/\/))+([\w.\/&=?\-~%;]+)\b/i"
,"<a href='$1$5' target='_blank' rel='nofollow'>$1$5</a>",$Output);
$Output=preg_replace("/\b([\w.]+)(#)([\w.]+)\b/i"
, "<a href='mailto:$1#$3'>$1#$3</a>",$Output);
return nl2br($Output);
}
}
I wanted to replace the rel='nofollow' with a php check of a MySQL dbase field and have it only put up the rel='nofollow' if the dbase field is empty. I tried to do it by replacing rel='nofollow' in the function with something like this which was my starting point:
<?php if (empty( $row_rswhatever['linkfollow'])) {echo "rel='nofollow'";}?>
or just this:
if (empty( $row_rswhatever['linkfollow'])) {echo "rel='nofollow'";}
I've tried it a hundred different ways (something good usually happens sooner or later) but cannot get it to work. I know from past experience that I am probably missing the boat on more than one issue, and would appreciate any help or guidance. Thanks.
A easy/lazy way to do it would be to continue doing it as you are doing now, however after the last $output=preg_replace add your if test and if you don't want the rel='nofollow', just use str_replace to remove it.
ie.
function ParseURLs($str)
{
if(isset($str)){
$Output=strip_tags($str);
$Output=preg_replace("/(\swww\.)|(^www\.)/i"," http://www.",$Output);
$Output=preg_replace("/\b(((ftp|http(s?)):\/\/))+([\w.\/&=?\-~%;]+)\b/i","<a href='$1$5' target='_blank' rel='nofollow'>$1$5</a>",$Output);
$Output=preg_replace("/\b([\w.]+)(#)([\w.]+)\b/i", "<a href='mailto:$1#$3'>$1#$3</a>",$Output);
if (empty( $row_rswhatever['linkfollow'])) {
$Output = str_replace(" rel='nofollow'", "", $Output);
}
return nl2br($Output);
}
}
Without knowing exactly what you'd be checking for in the database:
function ParseUrls($str) {
$sql = "SELECT ... FROM yourtable WHERE somefield='" . mysql_real_escape_string($str) ."'";
$result = mysql_query($sql) or die(mysql_error());
$rel = (mysql_num_rows($result) == 0) ? ' rel="nowfollow"' : '';
blah blah blah
}
Incidentally, the isset check is useless in your code. The function parameter does not have a default value (function x($y = default)), so if no parameter is specified in the calling code, it will cause a fatal error in PHP anyways.
This also assumes that you've already connected to MySQL elsewhere in your code, and are using the mysql library (not mysqli or pdo or db or whatever else).