title: WordPress - get shortcode attribute name
body: <p>Please tell how to retrieve available attributes of shortcode.</p>
  
  <p>I have the available shortcode but it won't show attribute name</p>
  
  <pre><code>global $shortcode_tags;
  print_r($shortcode_tags);
  </code></pre>
  
  <p>Someone told me to use PHP reflection API..</p>
  
  <p><strong>A working plugin code which get shortcode attribute:</strong></p>
  
  <pre><code>class ShortcodeReference {
  
      /**
       * Shortcode
       * @var string
       */
      private $_shortcode;
  
      /**
       * @var ReflectionFunction
       */
      private $_function_reflection;
  
      /**
       * @var string
       */
      private $_filepath;
  
      /**
       * Flat DocComments.
       * @var string
       */
      private $_description;
  
      /**
       * @var array
       */
      private $_attributes;
  
      /**
       * @var string
       */
      private $_function_name;
  
      /**
       * The tags that were found in the documentation
       * @var array
       */
      private $_known_tags;
  
      /**
       * - function name
       * - attribute(s)
       * - plugin or core
       */ 
      public function __construct($shortcode){
          global $shortcode_tags;
  
          if (!key_exists($shortcode, $shortcode_tags)){
              return false;
          }
  
          $this-&gt;_shortcode = $shortcode;
          $this-&gt;_function_name = $shortcode_tags[$shortcode];
  
          if (is_string($this-&gt;_function_name)){
              $this-&gt;_function_reflection = new ReflectionFunction($this-&gt;_function_name);
          } else if (is_array($this-&gt;_function_name)) {
              $this-&gt;_function_reflection = new ReflectionMethod ($this-&gt;_function_name[0],$this-&gt;_function_name[1]);
          }
      }
  
      /**
       * If no description for the function is found, it will parse the DocComment of the function and return it as a string. 
       */
      public function getDescription(){
          if ($this-&gt;_description == ''){
              $this-&gt;_known_tags = array();
              $desc = $this-&gt;_function_reflection-&gt;getDocComment();
              $parsed_desc = '';
              if ($desc){
                  $matches = preg_split('/\n/',$desc);
                  $start_pattern = '/w*\/\*\*w*/';
                  foreach ($matches as $match) {
                      if (preg_match($start_pattern, $match,$submatch)){
                          // skip it
                      } else if (preg_match('/w*\*\//',$match,$submatch)){
                          $offset = strpos($match,'*/')-1;
                          $final_line.= trim(substr($match,0,-$offset)).'
  ';
                          if ($final_line != ''){
                              $parsed_desc .= $final_line;
                          }
                      } else if (preg_match('/w*\*/',$match,$submatch)){
                          if (preg_match('/@/',$match,$submatch)){
                              $offset = strpos($match,'@')+1;
                              $tag = trim(substr($match,$offset,strlen($match)-$offset));
                              $this-&gt;addTagFromString($tag);
                          } else {
                              $offset = strpos($match,'*')+1;
                              $parsed_desc .= trim(substr($match,$offset,strlen($match)-$offset)).'
          ';
                          }
                      }
                  }
              }
              if ($parsed_desc == ''){
                  $parsed_desc = __('No documentation found. ','Shortcode Reference');
              }
              $this-&gt;_description = $parsed_desc;
          }
          return $this-&gt;_description;
      }
  
      /**
       * Will find where the targeted function is defined.
       * @return string
       */
      public function getReference(){
          $absolute_path = $this-&gt;_function_reflection-&gt;getFileName();
          $this-&gt;_filepath = $absolute_path;
          if (strpos($absolute_path, ABSPATH)&gt;=0){
              /**
               * Yay, it's from Wordpress!
               */
              $relative_path = str_replace(ABSPATH,'',$absolute_path);
              $is_native = strpos($relative_path, 'wp-includes/');
              $is_plugin = strpos($relative_path, 'wp-content/plugins/');
              if ($is_native !== false){
                  return 'WordPress function';
              } else if ($is_plugin !== false){
                  $plugin_path = explode('/',str_replace('wp-content/plugins/','',$relative_path));
                  return 'Plugin: '.$plugin_path[0];
              }
          }
          return 'PHP native';
      }
  
      /**
       * Retrieve the absolute file path
       *
       * @return string
       */
      public function getFilePath(){
          return $this-&gt;_filepath;
      }
  
      /**
       * Get the options for the function
       * 
       * @return array
       */
      public function getParameters(){
          $options = $this-&gt;_function_reflection-&gt;getParameters();
      }
  
      /**
       * Parse a string to a tag
       * @param string $string
       */
      private function addTagFromString($string){
          $tag = explode(' ',$string);
          $tagname = array_shift($tag);
          $this-&gt;_known_tags[$tagname] = implode(' ',$tag);
      }
  
      /**
       * Get the tags for the current documentation
       */
      public function getTags(){
          if (!is_array($this-&gt;_known_tags)){
              $desc = $this-&gt;getDescription();
          }
          return $this-&gt;_known_tags;
      }
  
      /**
       * Get the URL where you can find more information about the shortcode.
       * 
       * @return url
       */
      public function getUrl(){
  
          if (!$this-&gt;_url){
  
              $is_plugin = strpos($this-&gt;getReference(),'Plugin:');
              if ($this-&gt;getReference() == 'WordPress function'){
  
                  $this-&gt;_url ='http://codex.wordpress.org/index.php?title=Special:Search&amp;search='.$this-&gt;_shortcode.'_Shortcode';
              } else if ($is_plugin !== false){
                  $plugin_info = get_plugin_data($this-&gt;_filepath);
  
                  if (is_array($plugin_info) &amp;&amp; key_exists('PluginURI',$plugin_info)){
                      /**
                       * If you can find the plugin-url, use that
                       */
                      $this-&gt;_url = $plugin_info['PluginURI'];
                  } else if (is_array($plugin_info) &amp;&amp; key_exists('AuthorURI',$plugin_info)){
                      /**
                       * Else use the author-URI
                       */
                      $this-&gt;_url = $plugin_info['AuthorURI'];
                  } else {
                      /**
                       * If all else fails, Google is your friend
                       */
                      $this-&gt;_url = 'http://www.google.com/search?q=Wordpress+'.$plugin_path.'+'.$this-&gt;_shortcode;
                  }
              } else {
                  $this-&gt;_url = 'http://www.php.net/'.$this-&gt;_shortcode;
              }
          }
          return $this-&gt;_url;
      }
  }
  </code></pre>