PHP sort an array by lastname separated by whitespace in modx

我的未来我决定 提交于 2019-12-11 05:08:42

问题


I have a mysql table that looks like this:

id author public image1 image2 image3 bio media1 media2 media3 media4 media5 media6

The Field "author" normaly has Firstname (Secondname) Lastname seperated by whitespaces. How can I sort the array after the Lastname and if just one name is present after this one.

This is the modx query I use to sort after the author but obviously it doesn't use the lastname.

  $c = $modx->newQuery('AuthorDe');
  $c->sortby('author','ASC');
  $authors = $modx->getCollection('AuthorDe',$c);

回答1:


You're shooting yourself in the foot right now, for a couple of reasons:

  • When there is only one word in the string, the sorting is hard to predict.
  • You have indexes for your data for a reason. They make it a lot faster. Using string functions force a table scan. Good enough for 100 data units, slow for 10000 rows and 'database went for a vacation" at 1000000.
  • Next time you have to use the author field and you realize you have to split it up to words you also have to understand and fix this code snippet on top of the old ones.

That said - I haven't tested it - but try this:

$c->sortby('substring_index(author," ",-1)','ASC');



回答2:


So to elaborate on the very valuable point jous made, putting multiple points of data in one database column is counter productive. The sorting you want to do would be simple, fast, & efficient, in a sql query (using the same construct jous showed but without the string operation).
To modify this table you would simply add the following columns to your table in place of author:
firstname
lastname
middlename

To show you how simple this is (and make it even easier) here's the code to do it:

ALTER TABLE [tablename] 
ADD COLUMN firstname varchar(32) 
ADD COLUMN lastname varchar(32) 
ADD COLUMN middlename varchar(32)
DROP COLUMN author;

Then the modx PHP code would be:

$c->sortby('lastname','ASC');

So this is fairly easily done... and if you still need to support other references to author then create a view that returns author in the same way the un-altered table did as shown below (NOTE: you would still have to change the table name reference so it points to the view instead of the table... if this will be a big problem then rename the table and name the view the same as the old table was...):

CREATE VIEW oldtablename AS 
SELECT firstname+' '+middlename+' '+lastname' ' AS author
FROM newtablename;

NOTE: if you do create a view like the above then it is probably worth your while to add all of the other columns from the new table (the multiple image & media columns). NOTE2: I will add, however, that those would ideally be in separate tables with a join table to this one... but if I were in your spot I might agree that expedience might beat utility & future usability.... however if you did put them in different tables you could add those tables to this view (as joins to the new table) and still be able to support existing code that depends on the old table & it's structure.

While the above is all fairly easily done and will work with minor adjustments from you the last part of this is getting your custom table changes to be reflected by xPDO. If you are already comfortable with this and know what to do then great. If you aren't this is by far the best article on the topic: http://bobsguides.com/custom-db-tables.html

(Yes it is worth getting Bob's code as a snippet so all of this can simply be generated for you once the database changes have been made... (remember you will likely need to delete the existing schema file & xpdo related class files & map files before you run Bob's generation code, or your changes that have the same table name, like the view, won't take effect).

Hope this helps you (or the next person to ask a similar question).



来源:https://stackoverflow.com/questions/9582932/php-sort-an-array-by-lastname-separated-by-whitespace-in-modx

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!