PHP返回的json,Obj-C解析的一个例子

探讨PHP生成JSON字符串并使用Objective-C进行解析时出现的问题。错误在于PHP生成的JSON字符串被额外包裹了'string'关键字,导致Objective-C解析失败。

PHP返回的json,Obj-C无法解析  


PHP代码如下:

<?php

$arr = array(   


'name' =>'abc',  


'nick' => 'bbc'


);


$json_string = json_encode($arr);   


echo $json_string; 

?>

只是简单的返回一串json,OC代码如下:


    NSString *name = _username.text;

    NSString *pass = _password.text;

    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8888/login.php"];

    NSLog(@"%@",url);    

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];

    [request setHTTPMethod:@"POST"];

    NSString *str = [NSString stringWithFormat:@"name=%@&pass=%@",name,pass];

    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];

    [request setHTTPBody:data];

    NSData *received = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

     NSError *error;

    NSDictionary *result = [NSJSerialization JSONObjectWithData:received options:NSJSONReadingAllowFragments error:&error];

    NSString *str1 = [[NSString alloc]initWithData:received encoding:NSUTF8StringEncoding];

    NSLog(@"%@",str1);

    NSLog(@"%@",error);


打印出的日志是这样:

2014-03-04 10:17:17.179 word[50534:70b] http://127.0.0.1:8888/login.php

2014-03-04 10:17:17.469 word[50534:70b] string{"name":"abc","nick":"bbc"}

2014-03-04 10:17:17.470 word[50534:70b] Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Invalid value around character 0.) UserInfo=xxxxxxxx {NSDebugDescription=Invalid value around character 0.}


有人遇到过吗?折腾了好几个小时,完全没有进展。


你的php返回内容应该是{"name":"abc","nick":"bbc"}, 而不是string{"name":"abc","nick":"bbc"}

由于多了一个string, 因此json解析失败了


<think> 我们已经在之前的对话中分析了问题:在ThinkPHP5中返回数据时出现'variable type error: object'错误,并讨论了如何返回JSON数据。 现在用户明确要求:解决返回时出现'variable type error: object'问题并实现返回JSON数据的方法。 核心问题:当返回的数据包含对象时,框架内部处理可能出错,因为框架期望返回的是数组或可以被安全转换为字符串的类型,而不是对象。 解决方案:确保返回的数据是数组或已经被正确转换为JSON格式。ThinkPHP5提供了`json()`助手函数来返回JSON响应,并且会自动处理数据转换。 步骤: 1. 获取需要返回的数据(可能是从数据库查询得到的模型对象或对象集合)。 2. 将对象转换为数组(如果数据是对象或对象集合)或确保数据是数组格式。 3. 使用`json()`函数返回数据。 注意:在ThinkPHP5中,模型对象有一个`toArray()`方法,可以将模型实例转化为数组。对于模型集合,同样可以使用`toArray()`方法。 示例代码: 假设我们有一个User模型,我们想要返回id为1的用户信息。 错误的方式(直接返回模型对象): ```php public function getUser() { $user = User::get(1); return $user; // 直接返回对象可能导致类型错误 } ``` 正确的方式(转换为数组并使用json返回): ```php public function getUser() { $user = User::get(1); // 将模型对象转换为数组 $data = $user->toArray(); // 使用json函数返回,框架会自动设置Content-Type为application/json return json($data); } ``` 如果返回的是多个用户的集合(例如使用all方法): ```php public function getUsers() { $users = User::all(); // 将模型集合转换为数组 $data = $users->toArray(); return json($data); } ``` 另外,也可以直接使用`json`函数传入对象,但要注意`json`函数内部会检查数据类型,对于模型对象,它会自动调用`toArray`方法吗?实际上,在ThinkPHP5的`json`函数中,如果传入的是模型对象或集合,并不会自动转换。因此,我们需要显式转换。 但是,我们也可以利用模型对象的`hidden`或`visible`方法控制输出的字段,然后再转换为数组。 例如,隐藏密码字段: ```php public function getUser() { $user = User::get(1); $user->hidden(['password']); $data = $user->toArray(); return json($data); } ``` 或者,使用集合时: ```php public function getUsers() { $users = User::all(); // 遍历集合并隐藏密码字段 $users->hidden(['password']); $data = $users->toArray(); return json($data); } ``` 另外,ThinkPHP5还提供了更便捷的方法:直接在模型实例上使用`append`和`hidden`方法,然后使用`json`函数返回,但需要确保传入的是数组。不过,如果我们直接返回模型实例给`json`函数,框架会尝试将对象转换为数组,但为了安全起见,建议显式转换。 参考用户提供的引用[^1]:返回JSON数据时,应该使用`json`函数,并且确保传入的数据是数组或可以被正确JSON编码的数据类型。 因此,总结步骤: 1. 获取数据(可能是对象或对象集合)。 2. 转换为数组(使用`toArray()`方法)。 3. 使用`json`函数返回。 如果数据源是JSON文件(如引用[^1]中的例子),那么应该这样处理: ```php public function getJson() { $content = file_get_contents('./testjson/test9.json'); $data = json_decode($content, true); // 第二个参数为true,将JSON字符串转换为数组 return json($data); } ``` 注意:`json_decode`的第二个参数设置为`true`,这样解析出来的是数组而不是对象,然后再通过`json`函数返回,这样就不会出现对象类型错误。 如果数据源是外部API返回JSON字符串,同样使用`json_decode($content, true)`转换为数组再返回。 最后,注意ThinkPHP5的配置:在`config`目录下的`app.php`中可以设置默认的返回类型,例如: ```php // 默认输出类型 'default_return_type' => 'json', ``` 这样设置后,控制器中返回数组会自动转为JSON格式。但是,如果返回的是对象,则仍然会出错。因此,即使设置了默认返回类型为json,也要确保返回的数据是数组或标量,而不是对象。 因此,为了避免variable type error: object错误,无论是否设置默认返回类型,都应将对象转换为数组后再返回。 结论:在ThinkPHP5中,返回JSON数据并避免对象类型错误的关键在于确保返回给`json`函数的数据是数组(或可以被JSON编码的非对象类型)。 下面总结一个通用的方法: ```php // 在控制器方法中 public function someAction() { // 获取数据,可能是对象、对象集合或从JSON字符串解析得到的对象 $data = ...; // 将对象或对象集合转换为数组 if (is_object($data)) { // 如果数据是模型对象或集合,使用toArray方法 if (method_exists($data, 'toArray')) { $data = $data->toArray(); } else { // 其他对象,可以先用json编码再解码成数组 $data = json_decode(json_encode($data), true); } } // 返回JSON响应 return json($data); } ``` 但是,更推荐在获取数据时就直接处理成数组,例如使用数据库查询时设置返回类型为数组(在数据库配置中设置'resultset_type' => 'array'),或者查询时使用`fetchSql(false)`和`select()`返回数组。 这样,我们就可以避免variable type error: object错误,并正确返回JSON数据。 相关问题: §§相关问题§§ 1. 在ThinkPHP5中如何配置默认返回JSON格式? 2. 如何将ThinkPHP5模型查询结果直接转为数组? 3. 如何处理ThinkPHP5中JSON返回时的字段隐藏? </think> 在 ThinkPHP 5 框架中解决 `variable type error: object` 错误并正确返回 JSON 数据,需遵循以下核心原则和步骤: --- ### 一、问题本质分析 出现该错误是因为框架尝试将 **对象直接作为响应数据返回**,而 TP5 的响应系统要求返回基础数据类型(数组/字符串)。常见于: 1. 直接返回模型对象 `return User::find(1);` 2. 未处理的外部 JSON 解析对象 `json_decode($json)` 3. 数据库查询返回的对象集合 > 引用案例证明:直接返回 `json_decode()` 产生的对象会触发类型错误[^1] --- ### 二、解决方案(三步法) #### 步骤 1:数据获取时强制类型转换 ```php // 从文件读取 JSON $content = file_get_contents('data.json'); $data = json_decode($content, true); // 关键:第二个参数 true 转数组 // 数据库查询 $user = Db::name('user')->find(1)->toArray(); // 模型转数组 ``` #### 步骤 2:使用 TP5 的 JSON 响应方法 ```php public function getUser() { $user = User::get(1); return json($user->toArray()); // 正确返回 JSON } public function getJsonFile() { $data = json_decode(file_get_contents('data.json'), true); return json($data); // 框架自动处理 Content-Type } ``` #### 步骤 3:全局配置优化(可选) 在 `config/database.php` 中修改: ```php return [ 'resultset_type' => 'array', // 强制所有查询返回数组 ]; ``` --- ### 三、关键注意事项 1. **`json_decode()` 必须加参数** ```php // 错误:返回 stdClass 对象 $obj = json_decode('{"name":"John"}'); // 正确:返回关联数组 $arr = json_decode('{"name":"John"}', true); ``` 2. **模型/集合转换方法** | 数据类型 | 转换方法 | 示例 | |------------------|-------------------------|--------------------------| | 单个模型对象 | `->toArray()` | `User::find(1)->toArray()` | | 模型对象集合 | `->toArray()` | `User::all()->toArray()` | | 数据库查询结果 | `->select()->toArray()` | `Db::name('user')->select()->toArray()` | 3. **JSON 响应规范** TP5 的 `json()` 方法会自动: - 设置 `Content-Type: application/json` - 处理中文 Unicode 转义 - 转换对象为数组(需手动调用 `toArray()`) --- ### 四、完整案例演示 #### 场景:返回用户数据 API ```php // 控制器方法 public function userInfo($id) { // 获取数据(确保是数组) $user = User::get($id)->hidden(['password'])->toArray(); // 返回标准 JSON 响应 return json([ 'code' => 200, 'data' => $user ]); } ``` #### 输出结果: ```json { "code": 200, "data": { "id": 1, "name": "张三", "email": "zhangsan@example.com" } } ``` --- ### 五、调试技巧 若仍遇错误,添加类型检查: ```php if (is_object($data)) { throw new \Exception('返回数据包含对象!'); } // 或用日志记录 \think\Log::record(gettype($data)); ``` > 通过这三步操作,可彻底解决 `variable type error: object` 问题,同时符合 RESTful API 的 JSON 返回规范[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值