I have a function that I loop to to build an url. what I need is to get the result in a single string. This is the code.
// Create URL for accesories
function create_url($id) {
global $db_categories;
// Select category sublevels
$sql_cat="SELECT parent_id, seo_id FROM $db_categories WHERE category_id = '".$id."'";
$catres = mysql_query("$sql_cat") or die (mysql_error());
while($selected_cat = mysql_fetch_array($catres)) {
$cat_seo = $selected_cat['seo_id']. "/";
$output .= $cat_seo;
create_url($selected_cat['parent_id']);
}
return $output;
}
// Call function
$result_cat = create_url($cat["category_id"]);
echo $result_cat;
This work fine if I use echo and will output (I only use $depth to track the results)
category1/
category2/
category3/
etc...
The problem is that I don't know how to return the result into a single string instead of echo it. When I use return it only outputs the first result. like this.
category1/
I want the return to output.
category1/category2/category3/
I can't for my life find a solution for this.
Thank's
Related
I have an array of CSV values in my Database like category1[obj1,obj2,obj3..]
View
<?php echo $row_company->category1;?>
Controller
$row_company = $this->employers_model->get_company_details_by_slug($company_name);
The employers_model then calls a procedure which in turn executes the required query which displays the contents of row = category1 in this fashion,
obj1,obj2,obj3...
I want to be able to show this result without the commas and as a list like this
obj1
obj2
obj3..
I'm Using CodeIgniter MVC Framework, I have some vague idea about the uses of implode function, and came across preg_split too, But don't know where to start meddling around from, the view or the controller.
Any direction towards the solution would be appreciated.
Edit : row_company in detail.
$row_company = $this->employers_model->get_company_details_by_slug($company_name);
if(!$row_company){
redirect(base_url(),'');
exit;
}
$company_website = ($row_company->company_website!='')?validate_company_url($row_company->company_website):'';
$data['row_company'] = $row_company;
$data['company_logo'] = $company_logo;
$data['company_join'] = $company_join;
$data['company_website'] = $company_website;
$data['company_location'] = $company_location;
$data['title'] = $row_company->company_name.' jobs in '.$row_company->city;
$this->load->view('company_view',$data);
}
employers_model content
public function get_company_details_by_slug($slug) {
$Q = $this->db->query('CALL get_company_by_slug("'.$slug.'")');
if ($Q->num_rows > 0) {
$return = $Q->row();
} else {
$return = 0;
}
$Q->next_result();
$Q->free_result();
return $return;
}
the procedure itself get_company_details_by_slug
BEGIN
SELECT emp.ID AS empID, emp.sts1, pc.ID, emp.country, emp.city, pc.company_name, pc.company_description, pc.company_location, pc.company_website, pc.no_of_employees, pc.established_in, pc.company_logo, pc.company_slug, pc.category1, pc.category2, pc.category3, pc.company_join
FROM `pp_employers` AS emp
INNER JOIN pp_companies AS pc
WHERE pc.company_slug=slug AND emp.sts1 ='active';END
Figured it out after referring many codeigniter/php forums.
Pretty simple actually,
<?php $array = explode(',', $row_company->category1);
foreach ($array as $item)
{
echo "<li>$item</li>";
}
?>
Thank you Nigel for pointing out to use explode function.
Cheers
In this DataObject there is a user supplied field Title which has to be converted to a unique URL slug.
Desired Result: Duplicate URL's should get a suffix to its value. So saving 2 records with Title Foo should result in one record with foo as its value for column URL and the second record should have value foo-2 for the same column.
public function onBeforeWrite() {
parent::onBeforeWrite();
// Sanitize Title field to use for URL
$filter = URLSegmentFilter::create();
$this->URL = $filter->filter($this->Title);
// If URL is not unique, add suffix
$i = 1;
while($this->uniqueURL($this->URL)) {
$i++;
$this->URL = $this->URL . "-" . $i;
}
}
method: uniqueURL (within same class)
public function uniqueURL($URL) {
// Check if there is a record with the same URL
$existingURL = DataObject::get('NewsArticle', "URL = '$URL'");
if ($existingURL) {
// this is a duplicate URL
return false;
} else {
// this is a unique url
return true;
}
}
Saving Foo twice would result in foo and foo-2.
When saving two records with the same Title Foo results in two URL fields with foo
Why do you have two foo urls?
If you check your DB before inserting all records, this means that the check will not work on your record batch.
Don't use a loop to count unique urls
You don't need to loop and check every time and increment the count ($i). Performance wise youre far better off doing a COUNT() in a query and just use that value for your next insert.
// The following does exactly the same with just 1 query. No loop needed.
$count = DB::query("SELECT COUNT(*) FROM Table WHERE Title LIKE '{$filteredTitle}'")->value();
if ($count > 1) {
$filteredTitle .= "-" . $count;
}
$this->URL = $filteredTitle
Solutions
To do it onBeforeWrite() the only possibility is to Query your data AND check your records before they are saved.
Or a simpler solution with the same results is that you can change the url in an onAfterWrite() , and check use the amount of same titles as number.
public function onAfterWrite() {
parent::onAfterWrite();
// Sanitize Title field to use for URL
$filter = URLSegmentFilter::create();
$filteredTitle= $filter->filter($this->Title);
$count = DB::query("SELECT COUNT(*) FROM Table WHERE Title LIKE '{$filteredTitle}'")->value();
if ($count > 1) {
$filteredTitle .= "-" . $count;
}
$this->URL = $filteredTitle
}
Good day,
I am trying to create a form that will search for results in mysql DB and display the results using a loop. I have two options for searching, one using the ID and one using a string.The ID search works fine, as ID's are unique and one result is return which I can print out, but I am trying to adapt this to a function I can use for both, as the string should return a list results which will need to be looped through. The result is being returned as an object, and this is where I am struggling to get the loop to give a list of attributes and keys for each result, as it loops for each key=>Value fine, but need to know how to go through each object first, then the key=>Value.
In my class this is the find code i am using:
public static function find_by_qual_id($qual_id){
global $database;
$clean_qual_id = $database->escape_value($qual_id);
$result_array = static::find_by_sql("SELECT * FROM sdp WHERE qual_id='{$clean_qual_id}' LIMIT 1");
return !empty($result_array) ? array_shift($result_array) : false;
return $result_array;
}
On the page this is the loop (which does not work):
if(isset($qual_id)){
$qual_info = Qual_lookup::find_by_qual_id($search_qual_id);
if($qual_info != null){
echo "<h4>RESULTS FOUND FOR \"{$search_qual_id}\"</h4>";
echo "<div><form name=\"found_qual\"><table>";
foreach($qual_info as $qual){
foreach($qual as $key => $value){
echo "<tr><td>{$key} : </td><td">{$value}</td></tr>";
}
}
} else {
echo "No results found for \"{$search_qual_id}\"";
}
echo "</table></form></div>";
}
OK I found the problem... for some reason I have 2 return statements in the class:
return !empty($result_array) ? array_shift($result_array) : false;
return $result_array;
removing the first return statement now makes this work... it seems.
I know this has been done before. You can see an example of it whenever you post a new blog post/page in Wordpress, and the title is the same title as an existing page/post. Here's an example:
some-page-slug
some-page-slug-1
some-page-slug-2
How would you programmatically (using PHP) deal with someone submitting the slug of "some-page-slug" with the given list. Obviously, you should result in "some-page-slug-3", but what does that code look like? For some reason, this escapes me. I'm assuming, and hopefully I'm wrong, you would have to use jQuery (or vanilla js, whatever), correct?
Here's a possible solution like Mathew MacLeans suggested in his comment:
$slug = 'slug';
$slugs = array('slug', 'slug-1', 'slug-2', 'slug-5');
$result = $slug;
$i = 1;
while(in_array($result, $slugs)) {
$result = $slug . '-' . $i;
++$i;
}
// prints 'slug-3'
print $result;
Of course you have to replace in_array with your function that checks for existence of a slug.
Demo
Try before buy
Just some pseudo-code to get you going, but I believe this is the route you should take.
$postTitle = <WhateverTheTitleIs>;
$result = mysql_query("SELECT id FROM mytable WHERE title = '$postTitle'");
if(mysql_num_rows($result) == 0) {
// title not found, submit to database
} else {
// title exists
$postTitle = $postTitle + 1;
}
Now, obviously this isn't anywhere near 100% correct syntax, but it should more than point you in the direction that you need to go. :)
I asked this question before, but it got no responses, so I deleted the last question, and simplified/clarified the question, and am reposting
I have a comics site... I'm working on a SO-style tagging system. A user can select 1 or many tags which will display all associated comics.
To remember the user selections, I'm storing them in a $_SESSION array.
The issue I'm having is that one of the strings, 'business', being stored in the $_SESSION['tagnames'] array after it is chosen by the user is not being found in the array...
The way it's supposed to work is a user selects a tag, and to deselect it, they click it again... so I check if the string is in the $_SESSION... if it is, unset it... here is a snippet:
//var_dump shows these are both set fine when a user clicks on the tag they want
$tagid = (isset($_GET['tagid']) ? ($_GET['tagid']) : null);
$tagname = (isset($_GET['tagname']) ? ($_GET['tagname']) : null);
...
//Tag IDS are added and removed without issue:
//if tag id exists in $_SESSION['tags'] array, remove it
if ($key = array_search($tagid, $_SESSION['tagids'])) {
unset($_SESSION['tagids'][$key]);
}
else {
$_SESSION['tagids'][] = $tagid;
}
...
//but one of the tag names, 'business', is not being removed... and is actually added again even when I press F5 to refresh
if ($key = array_search($tagname, $_SESSION['tagname'])) {
unset($_SESSION['tagname'][$key]);
}
else {
$_SESSION['tagname'][] = $tagname;
}
This is a var_dump of the sql statement: It correctly shows the query being changed based on which tag id is selected.
Here's a var_dump of the $_SESSION['tagname']... you can see that it recognizes when tags 2 and 3 (differences and similarities) have already been added (I used array_search() to check), but it doesn't find tagid 1, 'business', even though it's clearly been added several times.
Here's the function that returns the selected tag names to the user:
function getSelectedTags() {
global $tagid, $tagname;
if ($key = array_search($tagname, $_SESSION['tagname'])) {
unset($_SESSION['tagname'][$key]);
}
else {
$_SESSION['tagname'][] = $tagname;
}
var_dump($_SESSION['tagname']);
foreach ($_SESSION['tagname'] as $tagname) {
echo '<span class="tags">' . $tagname . '</span>';
}
}
Any thoughts why tagname 'business' is the only thing causing an issue?
Even after I destroy the session, pressing F5 to refresh will automatically put tagname 'business' into the $_SESSION['tagname'] array.
EDIT: More comprehensive code:
Homepage.php: user clicks on returned tags from getDBTags() to add a tag to the $_SESSION array on imageDisplay.php
<h5>Tags</h5>
<?php echo getDBTags(); ?>
<br/>
<p>Your tags:</p>
<?php echo getSelectedTags(); ?>
imageDisplay.php: responsible for handling how images are filtered and displayed...
getDBTags() returns tag choices from the database so users can click on them:
function getDBTags() {
include 'dbconnect.php';
global $cat;
$sql = "SELECT tagid, tagname FROM tags";
$query = $mysqli->query($sql);
while ($row = $query->fetch_assoc()) {
echo '<span class="tags">'.$row['tagname'].'</span>';
}
mysqli_close($mysqli);
}
getFilters() decides how images should be filtered by having a dynamic query, then sends the query to pagination(), which displays filtered images on pages.
function getFilters() {
include 'dbconnect.php';
global $cat, $site, $table, $tagid;
$order = " ORDER BY date DESC";
//if tag id exists in $_SESSION['tags'] array, remove it
if ($key = array_search($tagid, $_SESSION['tagids'])) {
unset($_SESSION['tagids'][$key]);
}
//if it doesn't, add it
else {
$_SESSION['tagids'][] = $tagid;
}
//var_dump($_SESSION['tagids']);
if ($cat != null) $catquery = " AND catidFK = $cat";
else $catquery = null;
$sql =
"SELECT c.*, t.*
FROM comics c
INNER JOIN comictags ct ON (c.id = ct.comicID)
INNER JOIN tags t ON (t.tagid = ct.tagID)
WHERE ct.tagID IN ('" . implode(', ', $_SESSION['tagids']). "')
". $catquery ." " . $order;
if (!$mysqli->query($sql)) printf("<br /><b>Error:</b> %s\n", $mysqli->error);
$query = $mysqli->query($sql);
var_dump($sql);
mysqli_close($mysqli);
return $query;
}
getSelectedTags() returns the selected tag title back to the user so they can see what they've chosen. If they click on a tag again (returned from getDBTags() above), it will remove the tag from $_SESSION['tagname']. This is the problem area:
function getSelectedTags() {
global $tagid, $tagname;
if ($key = array_search($tagname, $_SESSION['tagname'])) {
unset($_SESSION['tagname'][$key]);
}
else {
$_SESSION['tagname'][] = $tagname;
}
//var_dump($key = array_search($tagname, $_SESSION['tagname']));
var_dump($_SESSION['tagname']);
foreach ($_SESSION['tagname'] as $tagname) {
echo '<span class="tags">' . $tagname . '</span>';
}
}
There are three issues which stand out (well two stand out, one is very subtle).
1. Open only one DB connection and leave it:
First, instead of opening and closing the connection in $mysqli in your functions, do it once at the start of the script and leave it open. You'll need to modify your functions to accept $mysqli as a parameter (preferred) or access it via global $mysqli; (not preferred). There is no need to call mysqli_close(), as that is done implicitly.
In your getFilters() function, you are actually closing the MySQLi resource $mysqli and then attempting to return $query; where $query is a result resource. Doing that will render the result resource useless.
// Pass $mysqli as a parameter
function getFilters($mysqli) {
//...
// Do alll your stuff...
// And do not call mysqli_close()!
return $query
}
2. Use strict comparison and test for FALSE with array_search():
When using array_search(), if your result is the first element in the array at key [0], that will be regarded by a surrounding if () condition as a falsy return rather than the positive result it should be. For that reason, a tag at position [0] will get repeatedly added rather than removed. This will need to be fixed in a couple of places...
// First get the key, which is an int or FALSE
$key = array_search($tagid, $_SESSION['tagids']);
// Unset if it is FALSE by strict comparison
if ($key !== FALSE) {
unset($_SESSION['tagids'][$key]);
}
else {
$_SESSION['tagids'][] = $tagid;
}
3. Global variable $tagname is ruined by a foreach:
You have accessed the global $tagname in getSelectedTags(). But in that function you have a foreach loop which does :
foreach ($_SESSION['tagname'] as $tagname)
When using $tagname as the loop's variable there, it is actually overwriting the global $tagname on each iteration. You need to change that to a different value, or whenever you call getSelectedTags(), $tagname the global will become whatever the last tag in $_SESSION['tagname'] had been, without exception.
// use a different varname in the loop
foreach ($_SESSION['tagname'] as $tn) {
// Also calling htmlspecialchars to escape here. Do this in any variable to HTML output...
echo '<span class="tags">' . htmlspecialchars($tn) . '</span>';
}