1

CakePHP を使用して JSONS を Android アプリケーションに送信しています。現在、モデルにこの関数があり、特定の場所の特定の半径内にある最も近い場所を取得します。

public function getNearest($lat = 54.980503, $lng = -1.614349, $radius = 25, $max = 30)
{
    $query = "SELECT *, 
             ( 3959 * acos( cos( radians('$lat') ) * cos(radians(`lat`)) 
             * cos(radians(`long`) - radians('$lng') ) 
             + sin( radians('$lat') ) * sin( radians(`lat`) ) ) ) 
             AS distance FROM locations HAVING distance < '$radius' ORDER BY distance LIMIT 0 , {$max}";
    return $this->query($query);        
}

これは私のコントローラーです:

class LocationsController extends AppController
{
    public $helpers = array('Html', 'Form');
    public $components = array('RequestHandler');
    public $viewClass = 'Json'; 
    function index()
    {
        $locations = $this->Location->getNearest(); 
        $this->set(compact('locations'));
        $this->set('_serialize', array('locations'));
    }
}

これは、通常の配列形式で得られる出力です。

array(2) 
{ 
    [0]=> array(2) 
    { 
        ["locations"]=> array(9) 
        { 
            ["id"]=> string(1) "1" 
            ["name"]=> string(20) "Newcastle University" 
            ["terrain"]=> string(1) "5" 
            ["difficulty"]=> string(1) "2"
            ["ratings"]=> string(1) "4" 
            ["uid"]=> string(1) "2" 
            ["long"]=> string(8) "-1.61624" 
            ["comid"]=> NULL 
            ["lat"]=> string(7) "54.9787" 
        } 
    [0]=> array(1) 
    { 
        ["distance"]=> string(19) "0.14548355269404845" 
    } 
 } 
 [1]=> array(2) 
 { 
    ["locations"]=> array(9) 
    {
        ["id"]=> string(1) "2" 
        ["name"]=> string(10) "Vale House" 
        ["terrain"]=> string(1) "4" 
        ["difficulty"]=> string(1) "3" 
        ["ratings"]=> string(1) "4"
        ["uid"]=> string(1) "2" 
        ["long"]=> string(8) "-1.58939" 
        ["comid"]=> NULL 
        ["lat"]=> string(7) "54.9849" 
    } 
    [0]=> array(1) 
    { 
        ["distance"]=> string(18) "1.0352356381517442" } 
    }
}

CakePHP で JSONView クラスをオンにすると、次のようになります。

{
   "locations":[
      {
         "locations":{
            "id":"1",
            "name":"Newcastle University",
            "terrain":"5",
            "difficulty":"2",
            "ratings":"4",
            "uid":"2",
            "long":"-1.61624",
            "comid":null,
            "lat":"54.9787"
         },
         "0":{
            "distance":"0.14548355269404845"
         }
      },
      {
         "locations":{
            "id":"2",
            "name":"Vale House",
            "terrain":"4",
            "difficulty":"3",
            "ratings":"4",
            "uid":"2",
            "long":"-1.58939",
            "comid":null,
            "lat":"54.9849"
         },
         "0":{
            "distance":"1.0352356381517442"
         }
      }
   ]
}

ご覧のとおり、そこには不要な文字列がたくさんあります。たとえば、なぜ 3 つの場所があるのでしょうか。なぜ距離は別なのですか?

出力が次の行に沿っている場合、それは素晴らしいことです:

{
    "locations":
    [{
            "id":"1",
            "name":"Newcastle University",
            "terrain":"5",
            "difficulty":"2",
            "ratings":"4",
            "uid":"2",
            "long":"-1.61624",
            "comid":null,   
            "lat":"54.9787"
            "distance":"0.14548355269404845"
    },
    {
            "id":"2",
            "name":"Vale House",
            "terrain":"4",
            "difficulty":"3",
            "ratings":"4",
            "uid":"2",
            "long":"-1.58939",
            "comid":null,
            "lat":"54.9849"
            "distance":"1.0352356381517442"
    }

   ]
}
4

1 に答える 1

2

@j0k が言及しているよう*に、SQL ステートメントでの使用は「データベース テーブルからすべての列を選択する」ことです。「距離」は計算フィールドであるため、特定のテーブルの「一部」ではないため、「場所」というプレフィックスは付けられません。CakePHP は、これらのフィールドを結果セットの別の「キー」に含めます。ただし、その結果配列の構造を書き直すのは難しくありません。

なぜ3つの場所があるのですか? データベースに「半径25以内の最大30の場所」を返すように要求しているため*クエリで(ただし、例には2つしか表示されていません)

カスタム クエリを使用していますが、値をエスケープ/サニタイズ しません。カスタムクエリを使用する場合、CakePHP はそれを行わず、SQL インジェクションを許可します。取り扱いに注意してください!CakePHP準備されたステートメントをサポートしていることに注意してください ( http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#prepared-statements )

最良のオプションは、クエリを標準の CakePHP に書き直すことfind()です。これを機能させるには、おそらくいくつかの virtualFields を作成する必要があります。http://book.cakephp.org/2.0/en/models/virtual-fields.html

現在、私は自分のコンピューターの前にいませんが、追加の例が必要な場合は、何かを書くことができるかもしれません

于 2013-03-03T17:49:34.070 に答える