5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

URLから特定のパラメーターを除外した形を返す関数(JavaScript/PHP)

Last updated at Posted at 2016-11-11

前置き

えらく雑に作られています。
案外考慮する点が多くて「とりあえずこれでいいか・・・・」と妥協した結果がこれだよ!!!
いい案(ロジック)があればご教授願いたい・・・・
※ 落ち着いたらブラッシュアップしていきます

コメントを頂けたおかげで、いくらかマシになりました!
(※『マシ』=> 提供いただいたスクリプトを改変してしまってるので・・・ )

投稿時に記載していなくて申し訳ないですが、下記ブラウザを対象としています。

  • IE10以上
  • FireFox
  • Chrome
  • Safari
  • (Edge) ※ 後々といったところです

本題

http://hoge.com/index.html?huga=true&hello=world&tanaka=tarou

みたいなURLがあったとします。

『hugaとhelloは非表示にしたいな~ :thinking:

ってときに↓こんな感じにトリミングしてくれる関数になります。(需要有るかな~~~)

http://hoge.com/index.html?tanaka=tarou

JavaScript版

使い方

script.js
var excludes = ['huga', 'hello']; // 除外したいパラメーターリスト
var url = "http://hoge.com/index.html?huga=true&hello=world&tanaka=tarou"; // トリム前のURL

console.log(trimToURL(excludes, url)); // レッツとりみんぐ!

関数

@mpywさんのコメントを参考にさせていただきました!
改変を加えたところだけ注釈を入れます。
※ URLインターフェース非対応ブラウザの処理は @yama-tさんが提供してくださったロジックに置き換えたほうが簡素ですね><

main.js

function trimToURL(excludes, url){
  var builder = { search: '', hash: '' }, baseUrl = url; /* builderオブジェクトを用意 */

  if ( !url ) return url;

  if ( typeof(URL) === "function" ) {
    var builder = new URL(url);
    baseUrl = builder.origin + builder.port + builder.pathname;
  }
  /* URLインスタンス非対応ブラウザ用 */  
  else {
    var tmpURL = url.split('?'), search = '', num = '', hash = '';
    // パラメーターを含んでいる場合
    if ( tmpURL[1] !== undefined ) {
      baseUrl = tmpURL[0]; // ? 以降を変数に格納
      search = tmpURL[1]; // ? 以降を変数に格納
      /* ハッシュの為の処理 */
      num = url.indexOf('#'); // # の位置を確認
      hash = (num > -1) ? url.substr(num) : ""; // # があった場合は、それ以降の文字列を変数に格納【更新(1)】
      search = '?' + search.replace(hash, ""); // # 以降の文字列をもとのURLから取り除き、変数に格納
      builder = { // エセURLインターフェースの戻り値作成
        search: search,
        hash: hash,
      };
    }
  }

  if (builder.search) {
    builder.search = "?" + builder.search.substr(1).split('&').filter(function (item) {
        return !excludes.hasOwnProperty(item.split('=', 2)[0]);
    }).join('&');
    builder.search = ( builder.search.search(/\?$/) < 0 ) ? builder.search : ""; // IE対策【更新(2)】
    // ↓現在はレガシーブラウザにも対応させる必要があったので悲しい書き方となっております
    return baseUrl + builder.search + builder.hash;
  }
  else {
    return url;
  }
}

更新(1)if ( -1 ) の結果はIEだとtrue, FireFoxとChromeとSafariだと falseのため、きちんと数値比較するようにしました。

before
      hash = (num) ? '#' + url.substr(num) : ""; // # があった場合は、それ以降の文字列を変数に格納

更新(2): filterの結果が空だった場合、? がFireFoxとChromeとSafariだと付与されなかったのですが、IEだと付与されるため、チェックを追加しました。

PHP版

使い方

index.php
$excludes = ['huga', 'hello']; // 除外したいパラメーターリスト
$url = "http://hoge.com/index.html?huga=true&hello=world&tanaka=tarou"; // トリム前のURL

echo trimToURL($excludes, $url); // レッツとりみんぐ!

関数

@mpywさんのコメントを参考にさせていただきました!
改変を加えたところだけ注釈を入れます。

index.php
function trimToURL($excludes, $url){
  $elements = parse_url($url);
  if (!isset($elements['query'])) return $url; // パラメーターがなかった場合は即時処理しない

  parse_str($elements['query'], $params);

  // パラメータが 「?hoge=huga」の形と 「?hoge」 の形に対応できるようにしたかったので処理を変えています
  $elements['query'] = "";
  // 現在ここがストレスです...
  foreach (array_diff_key($params, array_flip($excludes)) as $key => $val) {
    $elements['query'] .= ($elements['query'] !== "") ? "&" :  "";
    $elements['query'] .= (isset($val) && $val !== "") ? $key . "=" . $val : $key;
  }
  return build_url($elements);
}

function build_url(array $elements) {
    $e = $elements;
    return
        (isset($e['host']) ? (
            (isset($e['scheme']) ? "$e[scheme]://" : '//') .
            (isset($e['user']) ? $e['user'] . (isset($e['pass']) ? ":$e[pass]" : '') . '@' : '') .
            $e['host'] .
            (isset($e['port']) ? ":$e[port]" : '')
        ) : '') .
        (isset($e['path']) ? $e['path'] : '/') .
        (isset($e['query']) ? ( 
          is_array($e['query']) ?
            '?' . http_build_query($e['query'], '', '&') :
            (($e['query'] !== "") ? '?' . $e['query'] : '') /* パラメーターが無かった場合は「?」を付与しない */
        ) : '') .
        (isset($e['fragment']) ? "#$e[fragment]" : '');
}

ひとりごと

結構単純な配列加工にループ文って使いたくないですね(使わずにかけるとカコイイ!!)
javascriptでいうmapやfilterを駆使したり、PHPでいうarray_mapやarray_walk(これは最近聞いた)とか
慣れていきたいところです・・・。

5
6
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?