<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>9543建站博客</title><link>https://blog.9543.biz/</link><description>Good Luck To You!</description><item><title>微信小程序 页面跳转和数据传递</title><link>https://blog.9543.biz/post/076e1a04.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/微信小程序 页面跳转和数据传递.jpg&quot; alt=&quot;微信小程序 页面跳转和数据传递&quot;&gt;&lt;/p&gt;
&lt;p&gt;这篇文章主要介绍了微信小程序 页面跳转和数据传递实例详解的相关资料,这里附有实例代码帮助到家学习理解，需要的朋友可以参考下&lt;/p&gt;&lt;p&gt;&lt;strong&gt;微信小程序 页面跳转和数据传递&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1.先导&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在Android中，我们Activity和Fragment都有栈的概念在里面，微信小程序页面也有栈的概念在里面。微信小程序页面跳转有四种方式： &lt;/p&gt;&lt;p&gt;1.wx.navigateTo(OBJECT)； 2.wx.redirectTo(OBJECT)； 3.wx.switchTab(OBJECT)； 4.wx.navigateBack(OBJECT) 5.使用实现对应的跳转功能；&lt;/p&gt;&lt;p&gt;分析：&lt;/p&gt;&lt;p&gt;其中navigateTo是将原来的页面保存在页面栈中，在跳入到下一个页面的时候目标页面也进栈，只有在这个情况下点击手机的返回按钮才可以跳转到上一个页面；&lt;/p&gt;&lt;p&gt;redirectTo和switchTab都是先清除栈中原来的页面，然后目标页面进栈，使用这两种跳转方式，都不能通过系统的返回键回到上一个页面，而是直接退出小程序；&lt;/p&gt;&lt;p&gt;redirectTo使用的时候一定要配合tabBar或是页面里面可以再次跳转按钮，否则无法回到上一个页面；&lt;/p&gt;&lt;p&gt;switchTab跳转的页面必须是tabBar中声明的页面；&lt;/p&gt;&lt;p&gt;tabBar中定义的字段不能超过5个页面，小程序的页面栈层次也不能超过5层。&lt;/p&gt;&lt;p&gt;navigateBack只能返回到页面栈中的指定页面，一般和navigateTo配合使用。&lt;/p&gt;&lt;p&gt;wx.navigateTo 和 wx.redirectTo 不允许跳转到 tabbar 页面，只能用 wx.switchTab 跳转到 tabbar 页面&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2.页面跳转的具体操作&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;(1)wx.navigateTo(OBJECT)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;保留当前页面，跳转到应用内的某个页面，使用wx.navigateBack可以返回到原页面。&lt;/p&gt;&lt;thead&gt;&lt;th&gt;参数&lt;/th&gt;&lt;th&gt;类型&lt;/th&gt;&lt;th&gt;必填&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/thead&gt;urlString是需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔，参数键与参数值用=相连，不同参数用&amp;amp;分隔；如 ‘path?key=value&amp;amp;key2=value2&amp;#39;successFunction否接口调用成功的回调函数failFunction否接口调用失败的回调函数completeFunction否接口调用结束的回调函数（调用成功、失败都会执行）&lt;p&gt;示例代码：&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;wx.navigateTo({ url: &amp;#39;test?id=1&amp;#39;//实际路径要写全})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;//test.jsPage({ onLoad: function(option){ console.log(option.query)  }})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p&gt;注意：为了不让用户在使用小程序时造成困扰，我们规定页面路径只能是五层，请尽量避免多层级的交互方式。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（2）wx.redirectTo(OBJECT)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;关闭当前页面，跳转到应用内的某个页面。 &lt;/p&gt;&lt;thead&gt;&lt;th&gt;参数&lt;/th&gt;&lt;th&gt;类型&lt;/th&gt;&lt;th&gt;必填&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/thead&gt;urlString是需要跳转的应用内非 tabBar 的页面的路径，路径后可以带参数。参数与路径之间使用?分隔，参数键与参数值用=相连，不同参数用&amp;amp;分隔；如 ‘path?key=value&amp;amp;key2=value2&amp;#39;successFunction否接口调用成功的回调函数failFunction否接口调用失败的回调函数completeFunction否接口调用结束的回调函数（调用成功、失败都会执行）&lt;p&gt;示例代码：&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;wx.redirectTo({ url: &amp;#39;test?id=1&amp;#39;})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（3）wx.switchTab(OBJECT)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面&lt;/p&gt;&lt;p&gt;OBJECT 参数说明：&lt;/p&gt;&lt;thead&gt;&lt;th&gt;参数&lt;/th&gt;&lt;th&gt;类型&lt;/th&gt;&lt;th&gt;必填&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/thead&gt;urlString是需要跳转的 tabBar 页面的路径（需在 app.json 的 tabBar 字段定义的页面），路径后不能带参数successFunction否接口调用成功的回调函数failFunction否接口调用失败的回调函数completeFunction否接口调用结束的回调函数（调用成功、失败都会执行）&lt;p&gt;示例代码：&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;{ &amp;quot;tabBar&amp;quot;: { &amp;quot;list&amp;quot;: [{  &amp;quot;pagePath&amp;quot;: &amp;quot;index&amp;quot;,  &amp;quot;text&amp;quot;: &amp;quot;首页&amp;quot; },{  &amp;quot;pagePath&amp;quot;: &amp;quot;other&amp;quot;,  &amp;quot;text&amp;quot;: &amp;quot;其他&amp;quot; }] }}&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;wx.switchTab({ url: &amp;#39;/index&amp;#39;})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（4）wx.navigateBack(OBJECT)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;关闭当前页面，返回上一页面或多级页面。可通过 getCurrentPages()) 获取当前的页面栈，决定需要返回几层。&lt;/p&gt;&lt;p&gt;OBJECT 参数说明：&lt;/p&gt;&lt;thead&gt;&lt;th&gt;参数&lt;/th&gt;&lt;th&gt;类型&lt;/th&gt;&lt;th&gt;必填&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/thead&gt;deltaNumber1返回的页面数，如果 delta 大于现有页面数，则返回到首页。&lt;p&gt;示例代码：&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;// 注意：调用 navigateTo 跳转时，调用该方法的页面会被加入堆栈，而 redirectTo 方法则不会。见下方示例代码// 此处是A页面wx.navigateTo({ url: &amp;#39;B?id=1&amp;#39;})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;// 此处是B页面wx.navigateTo({ url: &amp;#39;C?id=1&amp;#39;})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;// 在C页面内 navigateBack，将返回A页面wx.navigateBack({ delta: 2})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;（5）使用&amp;lt;navigator/&amp;gt;标签实现页面跳转&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;navigator&lt;/p&gt;&lt;p&gt;页面链接。&lt;/p&gt;&lt;thead&gt;&lt;th&gt;参数&lt;/th&gt;&lt;th&gt;类型&lt;/th&gt;&lt;th&gt;必填&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/thead&gt;urlString应用内的跳转链接redirectBooleanfalse打开方式为页面重定向，对应 wx.redirectTo（将被废弃，推荐使用 open-type）open-typeStringnavigate可选值 ‘navigate&amp;#39;、&amp;#39;redirect&amp;#39;、&amp;#39;switchTab&amp;#39;，对应于wx.navigateTo、wx.redirectTo、wx.switchTab的功能hover-classStringnavigator-hover指定点击时的样式类，当hover-class=”none”时，没有点击态效果hover-start-timeNumber50按住后多久出现点击态，单位毫秒hover-stay-timeNumber600手指松开后点击态保留时间，单位毫秒&lt;p&gt;示例代码：&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;&amp;lt;navigator url=&amp;quot;navigate?title=navigate&amp;quot; hover-class=&amp;quot;navigator-hover&amp;quot;&amp;gt;跳转到新页面&amp;lt;/navigator&amp;gt; &amp;lt;navigator url=&amp;quot;redirect?title=redirect&amp;quot; open-type=&amp;quot;redirect&amp;quot; hover-class=&amp;quot;other-navigator-hover&amp;quot;&amp;gt;在当前页打开&amp;lt;/navigator&amp;gt; &amp;lt;navigator url=&amp;quot;index&amp;quot; open-type=&amp;quot;switchTab&amp;quot; hover-class=&amp;quot;other-navigator-hover&amp;quot;&amp;gt;切换 Tab&amp;lt;/navigator&amp;gt;&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3.页面的路由和生命周期&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;（1）页面的路由&lt;/p&gt;&lt;p&gt;在小程序中所有页面的路由全部由框架进行管理，对于路由的触发方式以及页面生命周期函数如下：&lt;/p&gt;&lt;thead&gt;&lt;th&gt;路由方式&lt;/th&gt;&lt;th&gt;触发时机&lt;/th&gt;&lt;th&gt;路由后页面&lt;/th&gt;&lt;th&gt;路由前页面&lt;/th&gt;&lt;/thead&gt;初始化小程序打开的第一个页面onLoad，onShow打开新页面调用 API wx.navigateTo 或使用组件onLoad，onShowonHide页面重定向调用 API wx.redirectTo 或使用组件onLoad，onShowonUnload页面返回调用 API wx.navigateBack 或用户按左上角返回按钮onShowonUnload（多层页面返回每个页面都会按顺序触发onUnload）Tab 切换调用 API wx.switchTab 或使用组件 或用户切换 Tab各种情况请参考下表&lt;p&gt;Tab 切换对应的生命周期（以 A、B 页面为 Tabbar 页面，C 是从 A 页面打开的页面，D 页面是从 C 页面打开的页面为例）：&lt;/p&gt;&lt;thead&gt;&lt;th&gt;当前页面&lt;/th&gt;&lt;th&gt;路由后页面&lt;/th&gt;&lt;th&gt;触发的生命周期（按顺序）&lt;/th&gt;&lt;/thead&gt;AANothing happendABA.onHide(), B.onLoad(), B.onShow()AB（再次打开）A.onHide(), B.onShow()CAC.onUnload(), A.onShow(）CBC.onUnload(), B.onLoad(), B.onShow()DBD.onUnload(), C.onUnload(), B.onLoad(), B.onShow()D（从分享进入）AD.onUnload(), A.onLoad(), A.onShow()D（从分享进入）BD.onUnload(), B.onLoad(), B.onShow()&lt;p&gt;&lt;strong&gt;4.参数传递&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;（1）通过路径传递参数&lt;/p&gt;&lt;p&gt;通过路径传递参数在wx.navigateTo(OBJECT)、wx.redirectTo(OBJECT)和&amp;lt;navigator/&amp;gt;中使用方法相同 示例代码：以wx.navigateTo为代表&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;&amp;quot;wx.navigateTo({ url: &amp;#39;test?id=1&amp;#39;//实际路径要写全})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;jb51code&quot;&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js;toolbar:false;&quot;&gt;//test.jsPage({ onLoad: function(option){ console.log(option.id)  }})&lt;/pre&gt;登录后复制&lt;p&gt;&lt;/p&gt;&lt;p&gt;参数与路径之间使用?分隔，参数键与参数值用=相连，不同参数用&amp;amp;分隔；&lt;/p&gt;&lt;p&gt;&lt;strong&gt;test?id=1 中id为参数键，1 为参数值 &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在目的页面中onLoad（）方法中option对象即为参数对象，可以通过参数键来取出参数值&lt;/p&gt;&lt;p&gt;以上就是本文的全部内容，希望对大家的学习有所帮助，更多相关内容请关注PHP中文网！&lt;/p&gt;&lt;p&gt;相关推荐：&lt;/p&gt;&lt;p&gt;微信小程序实现实时圆形进度条的方法&lt;/p&gt;&lt;p&gt;微信小程序 监听手势滑动切换页面的实现&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;clearfix&quot;&gt;&lt;/p&gt;&lt;p&gt;以上就是微信小程序 页面跳转和数据传递的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:04 +0800</pubDate></item><item><title>分享一个Android实现微信自动抢红包的代码实例</title><link>https://blog.9543.biz/post/22f89de1.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/分享一个Android实现微信自动抢红包的代码实例.jpg&quot; alt=&quot;分享一个Android实现微信自动抢红包的代码实例&quot;&gt;&lt;/p&gt;
&lt;p&gt;简单实现了微信自动抢红包的服务，原理就是根据关键字找到相应的View, 然后自动点击。主要是用到AccessibilityService这个辅助服务，基本可以满足自动抢红包的功能，但是有些逻辑需要优化，比如，拆完一个红包后，必须手动点击返回键，才能进行下一次自动抢红包。&lt;/p&gt;&lt;pre class=&quot;brush:java;toolbar:false&quot;&gt;AndroidManifest.xml   &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;manifest xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;    package=&amp;quot;com.jackie.webchatenvelope&amp;quot; &amp;gt;     &amp;lt;application        android:allowBackup=&amp;quot;true&amp;quot;        android:icon=&amp;quot;@mipmap/ic_launcher&amp;quot;        android:label=&amp;quot;@string/app_name&amp;quot;        android:theme=&amp;quot;@style/AppTheme&amp;quot; &amp;gt;        &amp;lt;activity            android:name=&amp;quot;.MainActivity&amp;quot;            android:label=&amp;quot;@string/app_name&amp;quot; &amp;gt;            &amp;lt;intent-filter&amp;gt;                &amp;lt;action android:name=&amp;quot;android.intent.action.MAIN&amp;quot; /&amp;gt;                 &amp;lt;category android:name=&amp;quot;android.intent.category.LAUNCHER&amp;quot; /&amp;gt;            &amp;lt;/intent-filter&amp;gt;        &amp;lt;/activity&amp;gt;         &amp;lt;service            android:enabled=&amp;quot;true&amp;quot;            android:exported=&amp;quot;true&amp;quot;            android:label=&amp;quot;@string/app_name&amp;quot;            android:name=&amp;quot;.EnvelopeService&amp;quot;            android:permission=&amp;quot;android.permission.BIND_ACCESSIBILITY_SERVICE&amp;quot;&amp;gt;            &amp;lt;intent-filter&amp;gt;                &amp;lt;action android:name=&amp;quot;android.accessibilityservice.AccessibilityService&amp;quot;/&amp;gt;            &amp;lt;/intent-filter&amp;gt;            &amp;lt;meta-data                android:name=&amp;quot;android.accessibilityservice&amp;quot;                android:resource=&amp;quot;@xml/envelope_service_config&amp;quot;/&amp;gt;        &amp;lt;/service&amp;gt;    &amp;lt;/application&amp;gt; &amp;lt;/manifest&amp;gt;   envelope_service_config.xml   &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;accessibility-service xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;    android:accessibilityEventTypes=&amp;quot;typeNotificationStateChanged|typeWindowStateChanged&amp;quot;    android:accessibilityFeedbackType=&amp;quot;feedbackGeneric&amp;quot;    android:accessibilityFlags=&amp;quot;&amp;quot;    android:canRetrieveWindowContent=&amp;quot;true&amp;quot;    android:description=&amp;quot;@string/accessibility_description&amp;quot;    android:notificationTimeout=&amp;quot;100&amp;quot;    android:packageNames=&amp;quot;com.tencent.mm&amp;quot; /&amp;gt;   activity_main.xml   &amp;lt;RelativeLayout xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;    xmlns:tools=&amp;quot;http://schemas.android.com/tools&amp;quot;    android:layout_width=&amp;quot;match_parent&amp;quot;    android:layout_height=&amp;quot;match_parent&amp;quot;    android:paddingBottom=&amp;quot;@dimen/activity_vertical_margin&amp;quot;    android:paddingLeft=&amp;quot;@dimen/activity_horizontal_margin&amp;quot;    android:paddingRight=&amp;quot;@dimen/activity_horizontal_margin&amp;quot;    android:paddingTop=&amp;quot;@dimen/activity_vertical_margin&amp;quot;    tools:context=&amp;quot;.MainActivity&amp;quot;&amp;gt;     &amp;lt;Button        android:id=&amp;quot;@+id/start&amp;quot;        android:layout_width=&amp;quot;wrap_content&amp;quot;        android:layout_height=&amp;quot;wrap_content&amp;quot;        android:padding=&amp;quot;10dp&amp;quot;        android:layout_centerInParent=&amp;quot;true&amp;quot;        android:textSize=&amp;quot;18sp&amp;quot;        android:text=&amp;quot;打开辅助服务&amp;quot;/&amp;gt; &amp;lt;/RelativeLayout&amp;gt;   MainActivity.java   package com.jackie.webchatenvelope;    import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.Toast;    public class MainActivity extends Activity {     private Button startBtn;        @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);            startBtn = (Button) findViewById(R.id.start);         startBtn.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 try {                     //打开系统设置中辅助功能                     Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);                     startActivity(intent);                     Toast.makeText(MainActivity.this, &amp;quot;找到抢红包，然后开启服务即可&amp;quot;, Toast.LENGTH_LONG).show();                 } catch (Exception e) {                     e.printStackTrace();                 }             }         });     }        @Override     public boolean onCreateOptionsMenu(Menu menu) {         // Inflate the menu; this adds items to the action bar if it is present.         getMenuInflater().inflate(R.menu.menu_main, menu);         return true;     }        @Override     public boolean onOptionsItemSelected(MenuItem item) {         // Handle action bar item clicks here. The action bar will         // automatically handle clicks on the Home/Up button, so long         // as you specify a parent activity in AndroidManifest.xml.         int id = item.getItemId();            //noinspection SimplifiableIfStatement         if (id == R.id.action_settings) {             return true;         }            return super.onOptionsItemSelected(item);     } }   EnvelopeService.java   package com.jackie.webchatenvelope; import android.accessibilityservice.AccessibilityService;import android.annotation.TargetApi;import android.app.Notification;import android.app.PendingIntent;import android.os.Build;import android.os.Handler;import android.util.Log;import android.view.accessibility.AccessibilityEvent;import android.view.accessibility.AccessibilityManager;import android.view.accessibility.AccessibilityNodeInfo;import android.widget.Toast; import java.util.List; /** * &amp;lt;p&amp;gt;Created by Administrator&amp;lt;/p&amp;gt; * &amp;lt;p/&amp;gt; * 抢红包外挂服务 */public class EnvelopeService extends AccessibilityService {     static final String TAG = &amp;quot;Jackie&amp;quot;;     /**     * 微信的包名     */    static final String WECHAT_PACKAGENAME = &amp;quot;com.tencent.mm&amp;quot;;    /**     * 红包消息的关键字     */    static final String ENVELOPE_TEXT_KEY = &amp;quot;[微信红包]&amp;quot;;     Handler handler = new Handler();     @Override    public void onAccessibilityEvent(AccessibilityEvent event) {        final int eventType = event.getEventType();         Log.d(TAG, &amp;quot;事件----&amp;gt;&amp;quot; + event);         //通知栏事件        if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {            List&amp;lt;CharSequence&amp;gt; texts = event.getText();            if (!texts.isEmpty()) {                for (CharSequence t : texts) {                    String text = String.valueOf(t);                    if (text.contains(ENVELOPE_TEXT_KEY)) {                        openNotification(event);                        break;                    }                }            }        } else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {            openEnvelope(event);        }    }     /*@Override    protected boolean onKeyEvent(KeyEvent event) {        //return super.onKeyEvent(event);        return true;    }*/     @Override    public void onInterrupt() {        Toast.makeText(this, &amp;quot;中断抢红包服务&amp;quot;, Toast.LENGTH_SHORT).show();    }     @Override    protected void onServiceConnected() {        super.onServiceConnected();        Toast.makeText(this, &amp;quot;连接抢红包服务&amp;quot;, Toast.LENGTH_SHORT).show();    }     private void sendNotificationEvent() {        AccessibilityManager manager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);        if (!manager.isEnabled()) {            return;        }        AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);        event.setPackageName(WECHAT_PACKAGENAME);        event.setClassName(Notification.class.getName());        CharSequence tickerText = ENVELOPE_TEXT_KEY;        event.getText().add(tickerText);        manager.sendAccessibilityEvent(event);    }     /**     * 打开通知栏消息     */    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)    private void openNotification(AccessibilityEvent event) {        if (event.getParcelableData() == null || !(event.getParcelableData() instanceof Notification)) {            return;        }        //以下是精华，将微信的通知栏消息打开        Notification notification = (Notification) event.getParcelableData();        PendingIntent pendingIntent = notification.contentIntent;        try {            pendingIntent.send();        } catch (PendingIntent.CanceledException e) {            e.printStackTrace();        }    }     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)    private void openEnvelope(AccessibilityEvent event) {        if (&amp;quot;com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI&amp;quot;.equals(event.getClassName())) {            //点中了红包，下一步就是去拆红包            checkKey1();        } else if (&amp;quot;com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI&amp;quot;.equals(event.getClassName())) {            //拆完红包后看详细的纪录界面            //nonething        } else if (&amp;quot;com.tencent.mm.ui.LauncherUI&amp;quot;.equals(event.getClassName())) {            //在聊天界面,去点中红包            checkKey2();        }    }     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)    private void checkKey1() {        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();        if (nodeInfo == null) {            Log.w(TAG, &amp;quot;rootWindow为空&amp;quot;);            return;        }        List&amp;lt;AccessibilityNodeInfo&amp;gt; list = nodeInfo.findAccessibilityNodeInfosByText(&amp;quot;拆红包&amp;quot;);        for (AccessibilityNodeInfo n : list) {            n.performAction(AccessibilityNodeInfo.ACTION_CLICK);        }    }     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)    private void checkKey2() {        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();        if (nodeInfo == null) {            Log.w(TAG, &amp;quot;rootWindow为空&amp;quot;);            return;        }        List&amp;lt;AccessibilityNodeInfo&amp;gt; list = nodeInfo.findAccessibilityNodeInfosByText(&amp;quot;领取红包&amp;quot;);        if (list.isEmpty()) {            list = nodeInfo.findAccessibilityNodeInfosByText(ENVELOPE_TEXT_KEY);            for (AccessibilityNodeInfo n : list) {                Log.i(TAG, &amp;quot;--&amp;gt;微信红包:&amp;quot; + n);                n.performAction(AccessibilityNodeInfo.ACTION_CLICK);                break;            }        } else {            //最新的红包领起            for (int i = list.size() - 1; i &amp;gt;= 0; i--) {                AccessibilityNodeInfo parent = list.get(i).getParent();                Log.i(TAG, &amp;quot;--&amp;gt;领取红包:&amp;quot; + parent);                if (parent != null) {                    parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);                    break;                }            }        }    }}&lt;/pre&gt;登录后复制&lt;p&gt;以上就是分享一个Android实现微信自动抢红包的代码实例的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:04 +0800</pubDate></item><item><title>thinkphp需要加载什么</title><link>https://blog.9543.biz/post/397db9b3.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/thinkphp需要加载什么.jpg&quot; alt=&quot;thinkphp需要加载什么&quot;&gt;&lt;/p&gt;
&lt;p&gt;随着互联网应用的不断发展，越来越多的 Web 开发者开始选择 PHP 作为开发语言，同时也采用了各种优秀的 PHP 框架来提高效率。其中，ThinkPHP 作为国内最受欢迎的 PHP 框架之一，在 WEB 开发中得到了广泛应用。在使用 ThinkPHP 框架时，需要理解框架所需要加载的内容和过程。本文将为大家介绍 ThinkPHP 框架加载所需的内容。&lt;/p&gt;环境要求&lt;p&gt;在使用 ThinkPHP 开发项目时，需要先了解框架所需的运行环境及其要求。具体来说，需要在服务器上安装 PHP 5.4.0 或更高版本，并开启与数据库中间件的通信支持，如 MySQL、Oracle、SQL Server 等。同时，还需要启用相应的扩展，如 PDO、Mbstring、Tokenizer 等。了解完环境要求后，就可以开始下载并使用 ThinkPHP 了。&lt;/p&gt;ThinkPHP 核心类&lt;p&gt;ThinkPHP 的核心类是控制器、模型、视图和配置文件。在使用框架时，需要先引入这些核心类。其中，控制器是 MVC 设计模式中的 C（Controller），负责处理用户请求和控制应用程序的流程。模型是 MVC 设计模式中的 M（Model），负责处理业务逻辑和与数据存取有关的操作。视图是 MVC 设计模式中的 V（View），负责将处理后的数据显示给用户。配置文件是应用程序运行的重要文件之一，保存了应用程序所需的配置数据。&lt;/p&gt;ThinkPHP 框架扩展库&lt;p&gt;在开发应用程序时，常常需要使用到各种功能模块，如分页、验证、缓存等，为了方便开发人员使用，ThinkPHP 提供了丰富的扩展库。这些扩展库可以方便地调用并集成到应用程序中。例如，针对分页功能，ThinkPHP 提供了 Page 类来实现分页操作。针对验证功能，ThinkPHP 提供了 Validate 类来实现验证操作。针对缓存功能，ThinkPHP 提供了 Cache 类来实现缓存操作。这些扩展库在实际开发中非常实用，可以大大提高开发效率。&lt;/p&gt;ThinkPHP 应用扩展&lt;p&gt;除了框架本身的扩展库，ThinkPHP 还提供了丰富的应用扩展，包括图片处理、文件上传、邮件发送等。这些扩展在 Web 开发中也是非常常用的。例如，使用 ThinkPHP 中提供的 Image 类可以轻松地对图片进行缩放、裁剪、加水印等操作。使用 ThinkPHP 中提供的 File 类可以轻松地实现文件上传、删除等操作。使用 ThinkPHP 中提供的 Mail 类可以轻松地实现邮件发送等操作。这些扩展极大地方便了开发人员。&lt;/p&gt;&lt;p&gt;总结&lt;/p&gt;&lt;p&gt;在使用 ThinkPHP 框架时，需要加载环境要求、核心类、框架扩展库和应用扩展。这些组成部分是框架开发的基础，也是实现应用程序功能的重要保证。掌握了这些内容，我们便能更好地使用 ThinkPHP 框架开发功能强大的 Web 应用程序。&lt;/p&gt;&lt;p&gt;以上就是thinkphp需要加载什么的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:03 +0800</pubDate></item><item><title>php 去掉数组中重复数据库</title><link>https://blog.9543.biz/post/219e97d2.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/php 去掉数组中重复数据库.jpg&quot; alt=&quot;php 去掉数组中重复数据库&quot;&gt;&lt;/p&gt;
&lt;p&gt;PHP是一门流行的服务器端编程语言，广泛用于开发Web应用程序。在PHP开发中，操作数据库是非常常见的需求之一。当我们从数据库中获取数据时，经常会出现数据重复的情况。如果我们需要对这些重复数据进行去重操作，可以使用PHP的数组去重的方法来实现。本文将介绍如何使用PHP去掉数组中的重复数据，并且将这些操作应用到数据库中。&lt;/p&gt;&lt;p&gt;一、PHP数组去重&lt;/p&gt;&lt;p&gt;1.使用array_unique()函数&lt;/p&gt;&lt;p&gt;PHP提供了array_unique()函数来实现数组去重。该函数可以返回去重后的数组，而不会改变原始输入的数组。使用示例如下：&lt;/p&gt;&lt;pre class=&#039;brush:php;toolbar:false;&#039;&gt;$array = array(&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;a&#039;, &#039;b&#039;);$result = array_unique($array);print_r($result);&lt;/pre&gt;登录后复制&lt;p&gt;输出：&lt;/p&gt;&lt;pre class=&#039;brush:php;toolbar:false;&#039;&gt;Array(    [0] =&amp;gt; a    [1] =&amp;gt; b    [2] =&amp;gt; c    [3] =&amp;gt; d)&lt;/pre&gt;登录后复制登录后复制&lt;p&gt;2.使用array_flip()和array_keys()函数&lt;/p&gt;&lt;p&gt;另一种方式是使用array_flip()函数将数组的键和值交换，然后再使用array_keys()函数取出键名数组。因为键名是唯一的，所以这种方法也能实现数组去重。使用示例如下：&lt;/p&gt;&lt;pre class=&#039;brush:php;toolbar:false;&#039;&gt;$array = array(&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;a&#039;, &#039;b&#039;);$result = array_keys(array_flip($array));print_r($result);&lt;/pre&gt;登录后复制&lt;p&gt;输出：&lt;/p&gt;&lt;pre class=&#039;brush:php;toolbar:false;&#039;&gt;Array(    [0] =&amp;gt; a    [1] =&amp;gt; b    [2] =&amp;gt; c    [3] =&amp;gt; d)&lt;/pre&gt;登录后复制登录后复制&lt;p&gt;两种方法的实现原理稍有不同，但都能实现数组去重。对于数据量较小的数组，两种方法都没有性能问题。但如果需要对大数据量的数组进行去重，第二种方法性能会更好。&lt;/p&gt;&lt;p&gt;二、PHP数组去重应用于数据库&lt;/p&gt;&lt;p&gt;现在假设有一个students表，其中有重复的记录，通过PHP去重函数将其去重后存入一个新的students表中。代码示例如下：&lt;/p&gt;&lt;pre class=&#039;brush:php;toolbar:false;&#039;&gt;&amp;lt;?php  //连接数据库  $servername = &amp;quot;localhost&amp;quot;;  $username = &amp;quot;username&amp;quot;;  $password = &amp;quot;password&amp;quot;;  $dbname = &amp;quot;myDB&amp;quot;;  $conn = new mysqli($servername, $username, $password, $dbname);  //检测连接  if ($conn-&amp;gt;connect_error) {    die(&amp;quot;Connection failed: &amp;quot; . $conn-&amp;gt;connect_error);  }  //从students表中获取数据  $sql = &amp;quot;SELECT * FROM students&amp;quot;;  $result = $conn-&amp;gt;query($sql);  //将数据存入一个数组  $array = array();  if ($result-&amp;gt;num_rows &amp;gt; 0) {    while($row = $result-&amp;gt;fetch_assoc()) {      $array[] = $row;    }  }  //使用array_unique()函数进行数组去重  $unique = array_unique($array, SORT_REGULAR);  //清空旧表  $sql = &amp;quot;TRUNCATE TABLE students&amp;quot;;  $conn-&amp;gt;query($sql);  //将去重后的数据插入新表  foreach($unique as $row) {    $sql = &amp;quot;INSERT INTO students (name,age,grade) VALUES (&#039;&amp;quot; . $row[&#039;name&#039;] . &amp;quot;&#039;,&amp;quot; . $row[&#039;age&#039;] . &amp;quot;,&amp;quot; . $row[&#039;grade&#039;] . &amp;quot;)&amp;quot;;    $conn-&amp;gt;query($sql);  }  //关闭数据库连接  $conn-&amp;gt;close();?&amp;gt;&lt;/pre&gt;登录后复制&lt;p&gt;在代码中，我们首先连接到数据库并从students表中获取数据，然后将数据存入一个数组中，使用array_unique()函数进行数组去重，最后将去重后的数据插入新表中。&lt;/p&gt;&lt;p&gt;三、结论&lt;/p&gt;&lt;p&gt;本文介绍了使用PHP数组去重的方法，包括使用array_unique()函数和array_flip()函数等方法。这些方法是实现数组去重的有效手段。此外，我们还将这些方法应用于数据库中，完成了从重复记录表中去重并存入新表的操作。这是PHP开发中非常常见的实际需求，在实际开发中可以灵活运用。&lt;/p&gt;&lt;p&gt;以上就是php 去掉数组中重复数据库的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:03 +0800</pubDate></item><item><title>完全掌握AWS S3在Laravel中的使用</title><link>https://blog.9543.biz/post/a242ad8f.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/完全掌握AWS S3在Laravel中的使用.jpg&quot; alt=&quot;完全掌握AWS S3在Laravel中的使用&quot;&gt;&lt;/p&gt;
&lt;p&gt;本篇文章给大家带来了关于在Laravel中使用AWS S3的相关知识，AWS S3为我们提供了存储服务器文件的地方，在云中存储文件不需要占用太多的磁盘空间，希望对大家有帮助。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;AWS S3 为我们提供了存储服务器文件的地方。 这样做有的好处是：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;备份 / 冗余&lt;/strong&gt; - S3 和类似产品具有内置备份和冗余&lt;/p&gt;&lt;p&gt;&lt;strong&gt;扩展 &lt;/strong&gt;- 在现代服务器（例如无服务器或容器化环境以及传统负载平衡环境）中，在服务器外保存文件成为了必要的&lt;/p&gt;&lt;p&gt;&lt;strong&gt;磁盘使用率&lt;/strong&gt; - 在云中存储文件时不需要太多的磁盘空间&lt;/p&gt;&lt;p&gt;&lt;strong&gt;功能 &lt;/strong&gt;- S3（和其他云）具有一些很棒的功能，例如对文件的版本控制、删除旧文件（或以更便宜的方式存储它们）的生命周期规则、删除保护等等&lt;/p&gt;&lt;p&gt;现在使用 S3（即使在单服务器设置中）从长远来看可以减少麻烦。 这是你应该知道的！&lt;/p&gt;配置&lt;p&gt;配置 S3 需要使用以下内容:&lt;/p&gt;&lt;p&gt;在 Laravel 中 - 通常通过 .env，但也可能在 config/filesystem.php 中&lt;/p&gt;&lt;p&gt;您的 AWS 账户&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Laravel Config&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果您检查您的 config/filesystem.php 文件，您会发现已有 S3 选项。 它已经设置为 .env 文件中的环境变量！&lt;/p&gt;&lt;p&gt;除非您需要对此进行自定义，否则您可以不理会它，只需在 .env 文件中设置：&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false&quot;&gt;#（可选）将默认文件系统驱动设置为 S3FILESYSTEM_DRIVER=sqs# 添加基于 S3 的文件驱动所需的参数AWS_ACCESS_KEY_ID=xxxzzzAWS_SECRET_ACCESS_KEY=xxxyyyAWS_DEFAULT_REGION=us-east-2AWS_BUCKET=my-awesome-bucketAWS_USE_PATH_STYLE_ENDPOINT=false&lt;/pre&gt;登录后复制&lt;p&gt;config/filesystem.php 文件包含以下选项 :&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false&quot;&gt;return [    &amp;#39;disks&amp;#39; =&amp;gt; [        // &amp;#39;local&amp;#39; 和 &amp;#39;public&amp;#39; 省略...        &amp;#39;s3&amp;#39; =&amp;gt; [            &amp;#39;driver&amp;#39; =&amp;gt; &amp;#39;s3&amp;#39;,            &amp;#39;key&amp;#39; =&amp;gt; env(&amp;#39;AWS_ACCESS_KEY_ID&amp;#39;),            &amp;#39;secret&amp;#39; =&amp;gt; env(&amp;#39;AWS_SECRET_ACCESS_KEY&amp;#39;),            &amp;#39;region&amp;#39; =&amp;gt; env(&amp;#39;AWS_DEFAULT_REGION&amp;#39;),            &amp;#39;bucket&amp;#39; =&amp;gt; env(&amp;#39;AWS_BUCKET&amp;#39;),            &amp;#39;url&amp;#39; =&amp;gt; env(&amp;#39;AWS_URL&amp;#39;),            &amp;#39;endpoint&amp;#39; =&amp;gt; env(&amp;#39;AWS_ENDPOINT&amp;#39;),            &amp;#39;use_path_style_endpoint&amp;#39; =&amp;gt; env(&amp;#39;AWS_USE_PATH_STYLE_ENDPOINT&amp;#39;, false),        ],    ],];&lt;/pre&gt;登录后复制&lt;p&gt;一些选项我们没有在 .env 文件中使用。例如，可以设置 AWS_URL，这对于使用具有 S3 兼容 API 的其他文件存储云是有用的，例如 CloudFlare 的 R2 或 Digital Ocean 的 Spaces。&lt;/p&gt;AWS 配置&lt;p&gt;在 AWS 中，您需要做两件事：&lt;/p&gt;&lt;p&gt;在 S3 服务中创建存储桶&lt;/p&gt;&lt;p&gt;创建一个 IAM 用户以获取 Key 和 Secret Key，然后将策略附加到该用户以允许访问 S3 API。&lt;/p&gt;&lt;p&gt;与 AWS 中的任何东西一样，在 S3 中创建存储桶需要查看大量配置选项，并想知道您是否需要其中的任何一个。 对于大多数用例，您不需要！&lt;/p&gt;&lt;p&gt;前往 S3 控制台，创建一个存储桶名称（它必须是全局唯一的，而不仅仅是您的 AWS 账户唯一），选择您操作的区域，并保留所有默认值（包括标记为 “阻止公共访问设置” 的区域）。&lt;/p&gt;&lt;p&gt;其中一些选项是您可能想要使用的，但您可以稍后选择它们。&lt;/p&gt;&lt;p&gt;创建存储桶后，我们需要对其执行操作的权限。 假设我们创建了一个名为 my-awesome-bucket 的存储桶。&lt;/p&gt;&lt;p&gt;我们可以创建一个 IAM 用户，选择 “编程访问”，但不要附加任何策略或设置任何其他内容。 确保记录秘密访问密钥，因为他们只会显示一次。&lt;/p&gt;&lt;p&gt;我创建了一个视频，展示了在此处创建存储桶和设置 IAM 权限的过程： www.youtube.com/watch?v=FLIp6BLtwj...&lt;/p&gt;&lt;p&gt;访问 &lt;code&gt;Access Key&lt;/code&gt; 和 &lt;code&gt;Secret Access Key&lt;/code&gt; 应放入您的&lt;code&gt; .env&lt;/code&gt; 文件中。&lt;/p&gt;&lt;p&gt;接下来，单击 IAM 用户并添加内联策略。 使用 JSON 编辑器对其进行编辑，然后添加以下内容（来自 Flysystem 文档）：&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false&quot;&gt;{    &amp;quot;Version&amp;quot;: &amp;quot;2012-10-17&amp;quot;,    &amp;quot;Statement&amp;quot;: [        {            &amp;quot;Sid&amp;quot;: &amp;quot;Stmt1420044805001&amp;quot;,            &amp;quot;Effect&amp;quot;: &amp;quot;Allow&amp;quot;,            &amp;quot;Action&amp;quot;: [                &amp;quot;s3:ListBuckets&amp;quot;,                &amp;quot;s3:GetObject&amp;quot;,                &amp;quot;s3:GetObjectAcl&amp;quot;,                &amp;quot;s3:PutObject&amp;quot;,                &amp;quot;s3:PutObjectAcl&amp;quot;,                &amp;quot;s3:ReplicateObject&amp;quot;,                &amp;quot;s3:DeleteObject&amp;quot;            ],            &amp;quot;Resource&amp;quot;: [                &amp;quot;arn:aws:s3:::my-awesome-bucket&amp;quot;,                &amp;quot;arn:aws:s3:::my-awesome-bucket/*&amp;quot;            ]        }    ]}&lt;/pre&gt;登录后复制&lt;p&gt;这使我们能够在我们的新存储桶上执行所需的 S3 API 操作。&lt;/p&gt;Laravel 用法&lt;p&gt;在 Laravel 中，你可以像这样使用文件存储：&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false&quot;&gt;# 如果您将 S3 设置为默认值：$contents = Storage::get(&amp;#39;path/to/file.ext&amp;#39;);Storage::put(&amp;#39;path/to/file.ext&amp;#39;, &amp;#39;some-content&amp;#39;);# 如果您没有将 S3 作为默认设置：$contents = Storage::disk(&amp;#39;s3&amp;#39;)-&amp;gt;get(&amp;#39;path/to/file.ext&amp;#39;);Storage::disk(&amp;#39;s3&amp;#39;)-&amp;gt;put(&amp;#39;path/to/file.ext&amp;#39;, &amp;#39;some-content&amp;#39;);&lt;/pre&gt;登录后复制&lt;p&gt;文件的路径（在 S3 中）被附加到存储桶名称中，因此名为 path/to/file.ext 的文件将存在于 s3://my-awesome-bucket/path/to/file.ext `。&lt;/p&gt;&lt;p&gt;从技术上讲，S3 中不存在目录。 在 S3 中，文件称为 “对象”，文件路径 + 名称是 “对象键”。 因此，在存储桶 my-awesome-bucket 中，我们刚刚创建了一个带有键 path/to/file.ext 的对象。&lt;/p&gt;&lt;p&gt;请务必查看 Laravel 文档的 Storage  以找到更多有用的使用 Storage 的方法，包括文件流和临时 URL。&lt;/p&gt;价钱&lt;p&gt;S3 相当便宜 —— 我们大多数人每月会花费几美分到几美元。如果您在使用完文件后从 S3 中删除文件，或者设置生命周期规则以在设定的时间段后删除文件，则尤其如此。&lt;/p&gt;&lt;p&gt;定价（主要）由 3 个维度驱动。价格因地区和用途而异。下面是一个基于给定月份的 Chipper CI (我的 Laravel 应用程序的 CI）实际应用程序使用情况的示例，它在 S3 中存储了大量数据：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;存储&lt;/strong&gt;: 每 GB 0.023 美元，~992GB ~= 22.82 美元&lt;/p&gt;&lt;p&gt;&lt;strong&gt;API 调用数量&lt;/strong&gt;: 约 700 万个请求～= 12 美元&lt;/p&gt;&lt;p&gt;&lt;strong&gt;带宽使用&lt;/strong&gt;: 这是非常不精确的。数据传输费用约为 23 美元，但这不包括基于 EC2 的带宽费用。&lt;/p&gt;关于 S3 的有用信息&lt;p&gt;如果您的 AWS 设置在私有网络中有服务器，并使用 NAT 网关，请务必创建一个 S3 端点（网关类型）。这是在 VPC 服务的 Endpoints 部分中完成的。这允许向 / 来自 S3 的调用绕过 NAT 网关，从而避免额外的带宽费用。使用它不需要额外费用。&lt;/p&gt;&lt;p&gt;如果您担心文件被覆盖或删除，请考虑在您的 S3 存储桶中启用 版本控制 &lt;/p&gt;&lt;p&gt;考虑在您的 S3 存储桶中启用 Intelligent Tiering ，以帮助节省您在旧文件后可能不会再次交互的文件的存储成本&lt;/p&gt;&lt;p&gt;请注意， 删除大存储桶（大量文件）可能会花钱！这是由于您必须进行大量 API 调用才能删除文件。&lt;/p&gt;&lt;p class=&quot;d-flex flex-wrap align-items-center &quot;&gt;相关推荐：Laravel视频教程&lt;/p&gt;&lt;p&gt;以上就是完全掌握AWS S3在Laravel中的使用的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:03 +0800</pubDate></item><item><title>使用PHP开发CMS系统中的语言细节問題解决</title><link>https://blog.9543.biz/post/d0422f3c.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/使用PHP开发CMS系统中的语言细节問題解决.jpg&quot; alt=&quot;使用PHP开发CMS系统中的语言细节問題解决&quot;&gt;&lt;/p&gt;
&lt;p&gt;随着网络技术的不断发展，很多人都开始使用CMS系统（Content Management System）来创建和管理他们的网站。而PHP是目前最流行的CMS系统的开发语言之一。但在使用PHP开发CMS系统时，我们经常会遇到一些语言细节问题，如何解决这些问题呢？&lt;/p&gt;&lt;p&gt;一、引用和复制变量的问题PHP语言中有两种常用的变量类型：值变量和引用变量。其中值变量表示一个实际的数值或字符串，而引用变量则是指向一个值变量的指针。在PHP中，有时候会遇到一个变量赋值给另一个变量的情况，这个时候需要注意赋值的是值变量还是引用变量。如果A变量是一个引用变量，而B变量赋给A变量，则B变量也会变成一个引用变量，两个变量指向同一内存地址。如果改变A变量的值，则B变量也会相应地改变。&lt;/p&gt;&lt;p&gt;而当我们想将一个值变量的值赋给另一个变量时，不能直接使用“=”，因为这样只是简单地将值变量的值复制给了另一个变量，不会产生引用。&lt;/p&gt;&lt;p&gt;因此，在CMS系统的开发中，需要特别注意变量之间的复制和引用，以避免出现不必要的问题。&lt;/p&gt;&lt;p&gt;二、类型转换的问题在PHP中，变量类型是自动确定的，将不同类型的值赋给一个变量时，会自动将其转换为合适的类型。这种自动类型转换机制可能会带来一些麻烦，因为转换的规则可能会和程序员所期望的不一样。&lt;/p&gt;&lt;p&gt;例如，在字符串中包含一个整数值时，程序员可能希望用字符串的形式显示，而不是将该值作为整数来处理。但是PHP的自动类型转换机制会将其转换为整数，这会导致字符串的显示结果和程序员所期望的不一样。&lt;/p&gt;&lt;p&gt;因此，在CMS系统的开发中，应当特别注意类型转换问题，程序员需要手动控制类型转换的过程，以确保程序的正确性。&lt;/p&gt;&lt;p&gt;三、变量作用域问题在PHP中，变量的作用域分为全局变量和局部变量两种。全局变量可以在程序的任何地方被访问到，而局部变量只能在其所在的代码块内被访问。&lt;/p&gt;&lt;p&gt;在CMS系统的开发中，可能会涉及到函数嵌套和文件包含等操作，这些操作可能会导致变量作用域混乱。因此，程序员应当尽可能避免使用全局变量，只使用局部变量，以保证程序的可维护性和可扩展性。&lt;/p&gt;&lt;p&gt;总之，在使用PHP开发CMS系统的过程中，需要特别注意语言细节问题，避免因为粗心大意而出现难以发现的错误。只有严谨的程序思维和良好的编码素养才能开发出稳定、高效的CMS系统，并为用户带来良好的使用体验。&lt;/p&gt;&lt;p&gt;以上就是使用PHP开发CMS系统中的语言细节問題解决的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:03 +0800</pubDate></item><item><title>vue不能用javascript</title><link>https://blog.9543.biz/post/956620a9.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/vue不能用javascript.jpg&quot; alt=&quot;vue不能用javascript&quot;&gt;&lt;/p&gt;
&lt;p&gt;Vue不能用JavaScript&lt;/p&gt;&lt;p&gt;JavaScript是一种广泛使用的编程语言，而Vue是一种基于JavaScript的前端框架。然而，不能说Vue不能使用JavaScript，因为Vue本身就是建立在JavaScript的基础上的。&lt;/p&gt;&lt;p&gt;Vue是什么？&lt;/p&gt;&lt;p&gt;Vue是一款轻量级、易于上手的前端框架，它使用模板语法和组件化开发模式来构建用户界面。Vue使用双向数据绑定来处理数据与界面的交互，并提供了许多灵活的生命周期函数，使得开发者可以针对具体的情况进行针对性的开发。&lt;/p&gt;&lt;p&gt;Vue的主要特点是：&lt;/p&gt;易于上手。Vue的语法很简单，并且有详细的文档和教程，学习起来非常容易。灵活方便。Vue提供了一系列的API和组件库，可以方便的进行开发，并且可以轻松的与其他库和框架进行整合。组件化开发。Vue将视图组件化，并提供一系列的生命周期函数，使得开发者可以轻松地控制组件的行为。&lt;p&gt;Vue与JavaScript的关系&lt;/p&gt;&lt;p&gt;Vue使用JavaScript作为其基础的编程语言，它可以通过JavaScript来实现数据的动态展示和处理。在Vue的开发中，我们会使用JavaScript来编写Vue的组件，使用Vue的API来调用Vue的功能。&lt;/p&gt;&lt;p&gt;例如，在Vue中我们可以使用JavaScript来定义一个组件：&lt;/p&gt;&lt;pre class=&#039;brush:JavaScript;toolbar:false;&#039;&gt;Vue.component(&#039;my-component&#039;, {  template: &#039;&amp;lt;div&amp;gt;{{ message }}&amp;lt;/div&amp;gt;&#039;,  data: function () {    return {      message: &#039;Hello Vue!&#039;    }  }})&lt;/pre&gt;登录后复制&lt;p&gt;这里我们使用了JavaScript来定义了一个名为my-component的组件，在组件的模板中使用了Vue的响应式数据绑定来展示数据。&lt;/p&gt;&lt;p&gt;而在实际使用中，我们会在HTML文件中引入Vue的库文件，然后再在JavaScript中实例化Vue对象来操纵网页内容：&lt;/p&gt;&lt;pre class=&#039;brush:HTML;toolbar:false;&#039;&gt;&amp;lt;div id=&amp;quot;app&amp;quot;&amp;gt;  &amp;lt;my-component&amp;gt;&amp;lt;/my-component&amp;gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;登录后复制&lt;pre class=&#039;brush:JavaScript;toolbar:false;&#039;&gt;var app = new Vue({  el: &#039;#app&#039;})&lt;/pre&gt;登录后复制&lt;p&gt;这里我们在HTML文件中应用了组件my-component，并在JavaScript中实例化了Vue对象。&lt;/p&gt;&lt;p&gt;总结&lt;/p&gt;&lt;p&gt;在实际开发中，我们不能说Vue不能使用JavaScript，因为Vue本身就是建立在JavaScript的基础上的。Vue与JavaScript密切相关，而且Vue提供了许多API和生命周期函数，使得JavaScript可以更加方便地用于前端开发。因此，在学习Vue之前，我们需要了解JavaScript的基本语法和使用方法。在学习过程中要多动手实践，体会Vue与JavaScript的联系，才能够更好地使用Vue开发前端网页。&lt;/p&gt;&lt;p&gt;以上就是vue不能用javascript的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:02 +0800</pubDate></item><item><title>Vue3中的directive函数：自定义指令扩展Vue3功能</title><link>https://blog.9543.biz/post/a611bfa7.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/Vue3中的directive函数：自定义指令扩展Vue3功能.jpg&quot; alt=&quot;Vue3中的directive函数：自定义指令扩展Vue3功能&quot;&gt;&lt;/p&gt;
&lt;p&gt;Vue3是目前最新的Vue版本，与Vue2相比，在许多方面都进行了升级和改进，其中一项改进便是directive函数。directive函数是Vue3中新增的函数，它可以用来自定义指令，以扩展Vue3的功能。&lt;/p&gt;&lt;p&gt;什么是指令？&lt;/p&gt;&lt;p&gt;指令是Vue提供的一种特殊的组件属性，用于在模板中添加特定的行为。可以将指令看作是一种AngularJS中常见的指令，它们可以对元素进行操作，改变其外观或行为。例如，Vue中常见的v-if、v-for、v-bind等都是指令。&lt;/p&gt;&lt;p&gt;Vue3中的指令是基于函数的。这意味着我们可以使用函数来创建自定义指令。这些指令函数需要在应用程序初始化之前与Vue相结合，并且可以用于元素、组件或其他DOM节点中。&lt;/p&gt;&lt;p&gt;指令函数的语法格式如下：&lt;/p&gt;&lt;pre class=&#039;brush:typescript;toolbar:false;&#039;&gt;const myDirective: Directive = {  beforeMount(el, binding, vnode) {    // ...  },  mounted(el, binding, vnode) {    // ...  },  beforeUpdate(el, binding, vnode, prevVnode) {    // ...  },  updated(el, binding, vnode, prevVnode) {    // ...  },  beforeUnmount(el, binding, vnode) {    // ...  },  unmounted(el, binding, vnode) {    // ...  }}&lt;/pre&gt;登录后复制&lt;p&gt;指令函数通过创建一个对象来定义。这个对象有六个方法，分别表示指令在挂载、更新和卸载期间的不同阶段。每个方法都有三个参数，分别是元素、绑定对象和虚拟节点。&lt;/p&gt;&lt;p&gt;在上面的代码中，我们可以看到每个函数都有三个参数：&lt;/p&gt;el（HTMLElement）：指令所绑定的元素。（例如：使用v-myDirective指令时，el就是绑定了该指令的元素）binding（DirectiveBinding）：一个包含指令信息的对象。（例如：包含指令的名称、值、参数等等）vnode（VNode）：Vue生成的虚拟节点。（例如：使用v-myDirective指令时，vnode就是包含该指令的组件或元素的虚拟节点）&lt;p&gt;接下来，我们来看看如何创建自定义指令。&lt;/p&gt;&lt;p&gt;创建自定义指令&lt;/p&gt;&lt;p&gt;为了创建自定义指令，我们需要使用Vue提供的directive函数：&lt;/p&gt;&lt;pre class=&#039;brush:typescript;toolbar:false;&#039;&gt;import { Directive } from &#039;vue&#039;const myDirective: Directive = {  beforeMount(el, binding, vnode) {    // ...  }}Vue.directive(&#039;my-directive&#039;, myDirective)&lt;/pre&gt;登录后复制&lt;p&gt;在这个示例中，我们使用directive函数来创建一个名为&lt;code&gt;my-directive&lt;/code&gt;的自定义指令，并将指令的定义传递给该函数。在这个例子中，我们只定义了&lt;code&gt;beforeMount&lt;/code&gt;钩子，这意味着在Vue实例的挂载过程中，这个指令函数将被调用。你可以根据自己的需求选择钩子函数。&lt;/p&gt;&lt;p&gt;使用自定义指令&lt;/p&gt;&lt;p&gt;一旦我们已经定义了一个自定义指令，我们就可以在Vue模板中使用它。我们可以使用特定的HTML属性来绑定指令，在Vue中这些属性以&lt;code&gt;v-&lt;/code&gt;前缀开头。例如：&lt;/p&gt;&lt;pre class=&#039;brush:html;toolbar:false;&#039;&gt;&amp;lt;div v-my-directive&amp;gt;这是一个自定义指令&amp;lt;/div&amp;gt;&lt;/pre&gt;登录后复制&lt;p&gt;在这个例子中，我们使用&lt;code&gt;v-my-directive&lt;/code&gt;将我们的自定义指令绑定到了一个&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;元素上。在Vue实例挂载该元素时，&lt;code&gt;beforeMount&lt;/code&gt;钩子将被调用。&lt;/p&gt;&lt;p&gt;小结&lt;/p&gt;&lt;p&gt;在Vue3中，指令成为了一个基于函数的API，通过使用directive函数来创建自定义指令。自定义指令可以用于元素、组件或其他DOM节点中，以扩展Vue的功能。&lt;/p&gt;&lt;p&gt;指令函数有六个生命周期钩子，分别映射到指令的不同状态。开发人员可以选择使用适当的钩子函数以在特定的阶段执行操作。&lt;/p&gt;&lt;p&gt;虽然指令的主要用途是实现DOM操作和交互行为，但使用自定义指令开发人员可以方便地将某些特定的行为封装在指令中，然后通过简单地在模板中调用指令实现这些行为，从而使得代码更加简洁、易于维护和扩展。&lt;/p&gt;&lt;p&gt;以上就是Vue3中的directive函数：自定义指令扩展Vue3功能的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:02 +0800</pubDate></item><item><title>WebSocket的使用详解</title><link>https://blog.9543.biz/post/dab3c7c6.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/WebSocket的使用详解.jpg&quot; alt=&quot;WebSocket的使用详解&quot;&gt;&lt;/p&gt;
&lt;p&gt;这次给大家带来WebSocket的使用详解，使用WebSocket的注意事项有哪些，下面就是实战案例，一起来看一下。&lt;/p&gt;&lt;p&gt;WebSocket初识 一：认识websocket websocket是html中一种新的协议，它实现了真正的长连接，实现了浏览器与服务器的全双工通信(指在通信的任意时刻，线路上存在A到B和B到A的双向信号传输)。 现在我们接触的协议大多是htttp协议，在浏览器中通过http协议实现了单向的通信，浏览器发出请求，服务器在响应，一次客户端与服务器的请求就结束了，服务器不能主动响应客户端，主动往客户端返回数据，而在某些需求上要实时刷新数据，获取服务器上的最新数据，显示给客户端。为了实现这样的需求，大多数公司使用了轮询的技术。轮询技术，在特定的时间间隔(如1秒)由浏览器发出http request，服务器再将最新数据返回给浏览器，实现了数据的实时刷新，很明显，通过这种技术实现的伪长连接，存在着一些缺陷，每隔一段时间的http request，不见得每一次的请求都是有意义的，因为客户端不会知道服务器上的数据有没有更新，这样在多次请求当中肯定会存在无效的请求（上一次请求回来的数据跟本次的完全一样）。 可见轮询这种技术，存在很大的弊端，而websocket实现了真正的长连接，服务器可以主动向客户端发送数据，正是这样的特点，就能很好的实现这种需求，当服务器有数据变化时，服务器就可以将新的数据返回给客户端，没有无效的请求回复。 在实现websocket连线过程中，需要透过浏览器发出websocket连线请求，然后服务器发出回应，这个过程通常称为“握手”（handshaking）。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;二：java实现websocket 1．服务器端实现 JSR356 的 WebSocket 规范使用 javax.websocket.*的 API，可以将一个普通 Java 对象（POJO）使用 @ServerEndpoint 注解作为 WebSocket 服务器的端点，代码示例如下： @ServerEndpoint(value=”/chatServer”) public class Chat {     private static Set sessions = Collections.synchronizedSet(new HashSet());     private static List messages = Collections.synchronizedList(new LinkedList());&lt;/p&gt;&lt;pre class=&quot;brush:php;toolbar:false&quot;&gt;private HttpSession httpSession;@OnOpenpublic void onOpen(Session session,EndpointConfig config) {    //to do somthing}@OnMessagepublic void onMessage(String message, Session session) {}@OnClosepublic void onClose(Session session, CloseReason reason) {}@OnErrorpublic void onError(Throwable t) {}}&lt;/pre&gt;登录后复制&lt;p&gt;代码解释： 上文的简洁代码即建立了一个 WebSocket 的服务端@ServerEndpoint(“/chatServer”) 的 annotation 注释端点表示将 WebSocket 服务端运行在 ws://[Server 端 IP 或域名]:[Server 端口]/demo/chatServer的访问端点，客户端浏览器已经可以对 WebSocket 客户端 API 发起 HTTP 长连接了。 使用@ServerEndpoint 注释的类必须有一个公共的无参数构造函数，  @onMessage 注解的 Java 方法用于接收传入的 WebSocket 信息，这个信息可以是文本格式，也可以是二进制格式。 @OnOpen 在这个端点一个新的连接建立时被调用。参数提供了连接的另一端的更多细节。Session 表明两个 WebSocket 端点对话连接的另一端，可以理解为类似 HTTPSession 的概念。 @OnClose 在连接被终止时调用。 使用注解方式很方便的建立了一个websocket 的服务器端，虽然代码简易，但在自己练习过程中，也是莫名其妙遇到很多问题，例如无论如何也连不上服务器，客户端只是报404错误，找不到。但是回头检查服务器端代码，貌似也没有什么问题，上网搜寻答案也没有符合自己想要的解决这种问题的答案，应该很多人都遇到了这种问题，很困惑。 不过，websocket实现的服务器端确实很好的实现一些特定的需求。 2．客户端实现 客户端是通过js代码连接服务器，首先得在服务器端建立一个websocket对象，再去连接服务器。 代码： &lt;/p&gt;&lt;pre class=&quot;brush:php;toolbar:false&quot;&gt;/******************************************************/ var msgContainer = document.getElementById(“msgContainer”); // 服务器地址 var wsUrl = “ws://127.0.0.1:8080/demo/chatServer”; // 创建WebSocket对象 var webSocket = new WebSocket(wsUrl); // 与服务器建立连接 webSocket.onopen = function() {     console.log(“与服务器连接成功！！”); } // 接收到服务器传来的消息 webSocket.onmessage = function(mes) {} // 服务器关闭 webSocket.onclose = function() {     console.log(“close!”); } // 服务器异常 webSocket.onerror = function() {     console.log(“error!”); } // 浏览器刷新或者关闭时，先关闭当前页面的webSocket对象 window.onbeforunload = function() {     webSocket.close(); } // 发送消息 function send() { webSocket.send(jsonMsg); } /******************************************************/&lt;/pre&gt;登录后复制&lt;p&gt;代码（var webSocket = new WebSocket(wsUrl);）是在申请一个 WebSocket 对象，参数是需要连接的服务器端的地址，同 HTTP 协议开头一样，WebSocket 协议的 URL 使用 ws://开头，另外安全的 WebSocket 协议使用 wss://开头。 WebSocket 对象一共支持四个消息 onopen, onmessage, onclose 和 onerror，有了这 4 个事件，我们就可以很容易很轻松的驾驭 WebSocket。 当 Browser 和 WebSocketServer 连接成功后，会触发 onopen 消息；如果连接失败，发送、接收数据失败或者处理数据出现错误，browser 会触发 onerror 消息；当 Browser 接收到 WebSocketServer 发送过来的数据时，就会触发 onmessage 消息，参数 mes中包含 Server 传输过来的数据；当 Browser 接收到 WebSocketServer 端发送的关闭连接请求时，就会触发 onclose 消息。我们可以看出所有的操作都是采用异步回调的方式触发，这样不会阻塞 UI，可以获得更快的响应时间，更好的用户体验。&lt;/p&gt;&lt;p&gt;相信看了本文案例你已经掌握了方法，更多精彩请关注9543建站博客其它相关文章！&lt;/p&gt;&lt;p&gt;推荐阅读：&lt;/p&gt;&lt;p&gt;如何使用H5的dataset&lt;/p&gt;&lt;p&gt;如何使用css3实现3d立体特效&lt;/p&gt;&lt;p&gt;以上就是WebSocket的使用详解的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:01 +0800</pubDate></item><item><title>jquery怎样去除ul里内容</title><link>https://blog.9543.biz/post/cf36b0d9.html</link><description>&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://img.9543.biz/img/jquery怎样去除ul里内容.jpg&quot; alt=&quot;jquery怎样去除ul里内容&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;jquery去除ul内容的方法：1、利用“$(ul元素)”语句获取指定的ul对象；2、利用html()方法去除获取到ul对象的内容，语法为“ul对象.html(&amp;#39; &amp;#39;);”。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;本教程操作环境：windows7系统、jquery1.10.0版本、Dell G3电脑。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;jquery怎样去除ul里内容&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在jquery中，可以给ul设置id属性，通过获得ul对象，使用html()设置ul对象内的为空，即可实现删除ul中的内容。下面举例讲解jquery中怎么删除ul中的内容。示例如下：&lt;/p&gt;&lt;p&gt;1、新建一个html文件，命名为test.html，用于讲解jquery中怎么删除ul中的整个li包括节点。使用ul标签创建一个列表，在列表ul下面，创建li元素、span元素。设置ul的id属性为myul，主要用于下面通过该id获得ul对象。&lt;/p&gt;&lt;p&gt;使用button标签创建一个按钮，按钮名称为“删除”。给button按钮绑定onclick点击事件，当按钮被点击时，执行delall（）函数。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2、在js标签中，创建delall()函数，在函数内，通过id(myul)获得ul对象，使用html()将ul对象内的所有元素置空，从而实现删除ul中的整个li包括节点。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;在浏览器打开test.html文件，点击按钮，查看实现的效果。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击按钮后：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;总结：&lt;/p&gt;&lt;p&gt;1、创建一个test.html文件。&lt;/p&gt;&lt;p&gt;2、在文件内，使用ul标签创建一个列表，在列表ul下面，创建li元素、span元素，同时创建一个button按钮，用于触发执行js函数。&lt;/p&gt;&lt;p&gt;3、在js标签内，创建函数，在函数内，通过id获得ul对象，使用html()将ul对象内的所有元素置空，从而实现删除ul中的整个li包括节点。&lt;/p&gt;&lt;p&gt;相关视频教程推荐：jQuery视频教程&lt;/p&gt;&lt;p&gt;以上就是jquery怎样去除ul里内容的详细内容，更多请关注9543建站博客其它相关文章！&lt;/p&gt;</description><pubDate>Sun, 19 Apr 2026 09:30:01 +0800</pubDate></item></channel></rss>