Yii - creating a link from data stored in a table - php

Ive been trying to think of / find a solution to an issue i have. Im creating a menu system for my Yii app but I need to store part of the items need for creating the URL in a table.
I have a table called system_menu_item:
---------------------------------------------------------------------|
item_id | dis_text | action | variables |
---------------------------------------------------------------------|
1 | edit article | document/view | array('id'=>$model->arl_id) |
What i was hoping for was:
$model = SystemMenuItem::model()->findByPk('1');
$url = yii::app()->createUrl($model->action, $model->variables);
This doesn't work.. I tried different ways of doing it all not working. Any ideas?
Thanks

I'm going to guess the issue is that $model->variables evaluates to a string with the value array('id'=>$mode->arl_id).
An ugly (and dangerous!) hack would be to read this in using eval()
A better way would be to probably figure out a different way to store your parameters, and read them into an array after performing your DB query.

Related

Multiply column with same content, make them count as "one"

About
I have this table in my database holding some information saved with a user id and time.
| CONTENT | USER ID | TIME |
| text | 1 | 1405085592 |
| hello | 2 | 1405085683 |
| hey | 1 | 1405086953 |
This example could be a data dump from my database, now as you can count there is "three" rows. However I only need to know how many users there have some information in my database. Therefor the result I'm really looking for is "two", because only two users have information in the database. User ID 1 is owning both "text"(1) & "hey"(3) where user ID 2 haves "hello"(2).
In short
I want to count how many users (regardless how many rows of information they have) there are inside my database.
** What I tried **
I tried to fetch every single row into an array and then using array_unique to count them together, works fine but I do not see this as a clean and best way to do this.
Then what?
I could use the array_unique and just use count to see how many rows there are, but I'm looking for something more clean. I tried to search for this, but I'm not actually sure what I should search for in term to hit something I'm looking for. After being stuck and though I wanted to learn something new, I wanted to post this problem here.
Note
I hope you guys can help me, I have tried to make it clear what I'm looking for and what I tried. If not please let me know. Sorry if some of the above contains misspelled words, incorrect grammar or is badly explained. I do not speak English daily, but I try my best.
You are looking for the DISTINCT keyword. It returns the count of unique values of a column:
SELECT COUNT(DISTINCT user_id)
FROM your_table
See example on SQL Fiddle.
This query:
SELECT DISTINCT user_id FROM table
will return just one row for every user in the table.

add array to a field in mysql

I have array :
$ids=[123,234,567,8910,11324,1];
how to add this to one field in mysql.
After adding check if this id exists if it does not then add it to the same field.
I am looking at something like this.How do I do that .I really appreciate any help .Thanks in Advance.:
---------------------
| all_blocked_users |
---------------------
| 123,234,567 |
---------------------
Right off the bat, let me tell you that storing CSV values in a database is almost never a good idea! It demonstrates poor database design and bad data integrity. It'll likely cause issues further down the line and make working with the data later much more difficult.
Anyway, that having been said, if you still wish to do this, you can use implode() to conver the array into a string, that can then be inserted into your MySQL database:
$dbString = implode(',', $ids);
It would be much better to store the blocked users in another link table.

Storing in array or in fields? Which is better? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Today I was working on my website and I asked myself a simple question.
Does storing an array with all informations is better than saving those one in different fields?
For example if I store a word, a password and a number in one field on the database in this way
+-------------+----------------------------------------------------------------+
| Field | Value |
+-------------+----------------------------------------------------------------+
| all | ["test","fa26be19de6bff93f70bc2308434e4a440bbad02","25468684888"] |
+-------------+----------------------------------------------------------------+
Is it better than saving it in this way?
+-------------+------------------------------------------+
| Field | Value |
+-------------+------------------------------------------+
| word | test |
| password | fa26be19de6bff93f70bc2308434e4a440bbad02 |
| number | 25468684888 |
+-------------+------------------------------------------+
I think that the first method is faster than the last one because you need only to SELECT one field and not three or more. What do you think about it?
The second method. By far.
You should never put more than one piece of data into a single column.
A single row of data shuld contain all the information you need:
id name password
1 Fluff itsASecret
2 Flupp Ohnoes
Basically, it has to do with updates, selects, searches and pretty much everything that databases do. They are made to do it on single columns, not little bits of data inside a string.
Taking your example, how do you update the password? How do you put an index on the user ID?
What if you also had a bit of data called "NumberOfVotes" If you had it all in one column in a pseudo-array, how do you get a tally of all the votes cast by all users? Would you REALLY want to pull each entry out into PHP, explode it out, add it to the running total and THEN display how many votes have been cast? What if you had a million users?
If you store everything in a ingle column, you could do a tally really easily like this:
select
sum(NumberOfVotes)
from
yourTableName
Edit (Reply to faster query):
Absolutely not, the time it takes to compelte a query will come down to two things:
1) Time it takes to execute the query
2) Time it takes to return all the data.
In this case, the time it takes to return the data will be the same, after all, the database is returning the same amount of bytes. However, with tables that are properly set up, just FINDING the right data will be faster by orders of magnitue.
As an example of how difficult it would be to simply USE a table that has the various bits of information all mumbled together, try to write a query to update the "number" value in the row that starts with the word "test".
Having said that, there are possibly some potential cases where it can in fact be okay to store multiple "fields" of data in one column. I once saw (and copied) an exceptionally interesting permissions system for users that stored the various permissions in binary and each digit in the number equated to being allowed/not being allowed to perform a certain type of action. That was however one interesting example - and is pretty much what I would call an exception that proves the rule :)
I think that the first method is faster
is your main problem actually. You are comparing solutions from only "is it faster" point of view. While you have no measure to tell if there is any difference at all. Or, if even there is, if such a difference does matter at all. So, the only your reason is a false one. While you completely overlook indeed important, essential reasons like proper database design.
Saving in separate fields is a lot more flexible as you are then able to easily search/manipulate data using SQL queries, whereas if they were in an array you would frequently find yourself needing to parse data outside SQL. Consider the following example:
+-------------+----------------------------------------------------------------+
| Field | Value |
+-------------+----------------------------------------------------------------+
| all | ["1","fa26be19de6bff93f70bc2308434e4a440bbad02","25468684888"] |
+-------------+----------------------------------------------------------------+
Using the above table, you need to find the number field for the user with id 1, however there is nothing to search for, you can't simply to a query for the value 1 somewhere in the all field, as that would find every instance of the number 1!
You'll also encounter this problem when changing data in your DB, as you'll have to get the current array, parse it, change the value, then reinsert it.
Also you'll need to put some form of ID as a field to act as a primary key.
However with separate fields for each value, it's fairly simple:
+-------------+------------------------------------------+
| Field | Value |
+-------------+------------------------------------------+
| id | 1 |
| password | fa26be19de6bff93f70bc2308434e4a440bbad02 |
| number | 25468684888 |
+-------------+------------------------------------------+
SELECT `number` FROM mytable WHERE id = 1
The second option is better because its more readable and maintainable.
If someone who didnt write the code has to maintain it, the first option is terrible.
If you ever need to change a field, or add a field, likewise, the first option is a nightmare.
The second option requires much less work.
Keep it simple!
I think given example is trivial and that's why answer for specific example is 2nd method. But there are time's when first method is far more easy to implement. For example you create pages for website dynamically from admin panel, and in start you don't know all the values that will be used in every page. So you put general options like in 2nd method, and put something like page_data and use it to store serialized object. Now you should use serialized object for data that are not likely to change individually, as they are treated as single piece of data.
In your code you fetch serialized object, do unserialize and use them as normal. This way you can add page specific data that are not generalized for every page, but still the page's are the same.

Serialize vs Implode

What do you think is the better way to go about storing a few image id's inside a record in a MySQL database? It's just the image id's which will be used to fetch the images from a different library.
Do i implode the id's in the record like 1#4#7#9#10#12 or do I just serialize the array and store that? Are there any performance benefits by using the one instead of the other? Stability preferences?
I have just always used implode and explode, never really gave it much thought.
Thanks.
If you don't want to (over?)normalize your tables, and you really just want to store a list of ids then I suggest using a simple comma-separated list, because already MySQL has some functions which can directly deal with comma-separated string values:
FIND_IN_SET:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set
SELECT FIND_IN_SET('b','a,b,c,d'); --> 2
CONCAT_WS: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws
SELECT CONCAT_WS(',','First name',NULL,'Last Name'); --> 'First name,Last Name'
Of course, you won't be able to do SQL JOINs, but it still can be helpful.
I would pefer serialize or JSON-encode.
It is more flexible and for example will allow you to add image title and other details there in future...
As far as I know there are not significant differences in this case but implode() is a bit faster since it assumes an array and serialize() does not know what you are passing to it.
EDIT based on OP's comment:
Well all the images are stored in a seperate library table with the title and descriptions and things like that. But yeah I see your point.
In that case is not a good idea so serialize several IDs into a single field. What you need is a *-to-Many relation between your 2 tables. This is the correct way of represent multivalued fields:
+----------------------+
| USER |
+---------+------+-----+
| user_id | name | ... |
+---------+------+-----+
+----------------------+
| USER_PICTURE |
+---------+------------+
| user_id | picture_id |
+---------+------------+
+--------------------------+
| PICTURE |
+------------+-------+-----+
| picture_id | title | ... |
+------------+-------+-----+
My friend, serialization is to obtain a string representation of an object's status. Even if it works i don't think is the best way to do what you want. I would prefer to store a json object with the ids. Because a json object is multiplatform, is a string and is easily readable by a human i think is a good approach.

Making a database scalable

I've been developing a website for some time now and so far everything is fast and good, though that is with one active user. I don't know how many people will use my website in the first, week, month or year.
I've been looking into what scaling means and how to achieve it and caching seems to be a big part of it. So I started searching for ways to cache my content. Currently I've just developed the website in XAMPP. I'm using MySQL for the database and simple PHP with MySQLi to edit the data. I also do some simply logging with the built-in System Messages app in OS X Mountain Lion. So I'm thinking about using Memcache for the caching.
Is this a good approach?
How can I test it to really see the difference?
How do I know that it will work great even with many more users?
Are there any good benchmarking apps out there?
There are many ways to make sure that a database scales well, but I think the most important part is that you define proper indexes for your tables. At least the fields that are foreign keys should have an index defined.
For example, if you have a large forum, you might have a table of topics that looks like this:
topic_id | name
---------+--------------------------------
1 | "My first topic!"
2 | "Important topic"
3 | "I really like to make topics!"
... | ...
7234723 | "We have a lot of topics!"
And then another table with the actual posts in the topics:
post_id | user | topic_id
---------+------------+---------
1 | "Spammer" | 1
2 | "Erfa" | 2
3 | "Erfa" | 1
4 | "Spammer" | 1
... | ... | ...
87342352 | "Erfa" | 457454
When you load a topic in your application, you want to load all posts that match the topic id. In this case, you cannot afford to look through all database rows, because there are simply too many! Fortunately, you do not have to do much to make sure this is done, you just have to create an index for the field topic_id and you are done.
This is a very basic thing to do to make your database scale well, but since it is so important, I really thought someone should mention it!
Get and Use jMeter.
with jMeter you can test how quick responses are coming back and how pages are loading in addition to confirming that there aren't any errors currently going on. This way you can simulate a ton of load; while seeing actual performance updates when making an adjustment such as using memcache.

Categories