开发者

Better solution to variable argument function?

This is what I have now:

 function getAlbum(){
     $args = func_get_args();

     if(!(count($args) % 2) || count($args) == 1) {
         trigger_error('Argument count must be an odd number and greater than one.');
         return false;
     }

     $q = new Query("album_manager");
     $q->select($args[0]);
     unset($args[0]);
     call_user_func_array(array($q, "where"),$args);
     $q->limit(1);
     return send_back_as_array($q);
 }

If you call getAlbum('*','cid',1) you get all attributes where cid=1

If you call getAlbum('cid, anchor', 'cid',1) you get the anchor and cid where cid=1

It works fine, except I am worried that when someone is debugging the code, they might mistake the , between cid and anchor for an argument separator and get confused.

Does anyone have a m开发者_运维技巧ore elegant solution? I am just interested.

I thought about changing it to where it accepts getAlbum('cid','anchor','where:','cid',1) but I'm not sure that will be any better.

This is what I changed it to:

function getAlbum(){
    // argument one is a comma separated value or an array of what is requested.
    // the rest of the args must be an even number (odd number of args overall)
    // ever even argument is a selector and every odd is a condition 'selector = condition' in query
    // Examples:
    //      getAlbum('*','cid',1);   <-  Select all attributes from album where cid = 1
    //      getAlbum('cid','anchor','test','name','This is a test'); <- select cid from album where anchor = 'test' and 'name' = 'This is a test'
    //      getAlbum(array('cid','anchor'),'test','name'); select cid and anchor where 'test'='name'
    //      getAlbum('cid, anchor','cid',1); select cid and anchor where cid=1
    $args = func_get_args();
    if(!(count($args) % 2) || count($args) == 1) {
        trigger_error('Argument count must be an odd number and greater than one.');
        return false;
    }
    $q = new Query("album_manager");
    $q->select((is_array($args[0]) ? implode(", ",$args[0]) : $args[0]));
    unset($args[0]);
    call_user_func_array(array($q, "where"),$args);
    $q->limit(1);
    $array = send_back_as_array($q);
    if(count($array) != 1) return false;
    else return $array;
}


How about an array, and imploding its elements with a comma?

$q->select(is_array($args[0]) ? implode(', ', $args[0]) : $args[0]);

Calling code:

getAlbum(array('cid', 'anchor'), 'cid', 1);

EDIT: well then it sounds like that's the way to go since the select() method handles arrays automatically.


You could do something like:

$album = Album::select('cid', 'anchor')->where('cid', 1)->findOne();
$albums = Album::select('cid', 'anchor')->find();

The select function could return a new instance of some sort of query builder. Each of the member functions of it would return $this so that you could chain calls together. The final find() method could be optional if the query builder implements an iterator, because you could just do this in most cases:

foreach(Album::select('cid', 'anchor') as $album) {}

There are several different ways you could chain together like that; I'm not advocating the above style as the best version, but just a simple illustration of one of those ways.

If you aren't looking at doing such a radical change, there's not much that will make what you're trying to do any more clear. A couple of possibilities: You could combine your selected fields into a single string or array, or you could use named array parameters (but that will get verbose in a hurry).


Depending on what/how the function is being used, try passing an array to the function instead. Inside the function be sure to set defaults if needed (if variables are not passed) then resume like normal. ie:

function getAlbum($options) {
  $fields = array_key_exists('fields', $options) ? $options['fields'] : '';
  $where = array_key_exists('where', $options) ? $options['where'] : array();

  [do stuff]

  return $data;
}

$options = array('fields' => 'cid,anchor',
                 'where' => array('cid' => 1)
);

This way as your function evolves you can pass additional values with having to worry about changing structure/order of parameters later on.


I think, I'd prefer getAlbum(array('cid','anchor'),'cid',1). That looks quite clear to me and depending on the use case you could write:

getAlbum(array(
    'cid',
    'anchor'
),'cid',1)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜